diff -Nru ukui-screensaver-4.20.0.0/debian/changelog ukui-screensaver-4.20.0.0/debian/changelog --- ukui-screensaver-4.20.0.0/debian/changelog 2024-12-17 13:37:23.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/changelog 2025-02-13 20:26:40.000000000 +0800 @@ -1,3 +1,21 @@ +ukui-screensaver (4.20.0.0-ok3.3) huanghe; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他改动说明:增加单元测试;迁移控制面板锁屏、屏保插件 + * 其他改动影响域:无 + + -- Yang Min <yangmin@kylinos.cn> Thu, 13 Feb 2025 20:26:40 +0800 + +ukui-screensaver (4.20.0.0-ok3.2) huanghe; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他改动说明:同步v11-2503代码修改 + * 其他改动影响域:无 + + -- Yang Min <yangmin@kylinos.cn> Fri, 03 Jan 2025 19:14:46 +0800 + ukui-screensaver (4.20.0.0-ok3.1) huanghe; urgency=medium * BUG号:无 diff -Nru ukui-screensaver-4.20.0.0/debian/control ukui-screensaver-4.20.0.0/debian/control --- ukui-screensaver-4.20.0.0/debian/control 2024-12-17 13:37:23.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/control 2025-02-13 20:26:40.000000000 +0800 @@ -35,12 +35,15 @@ libavformat-dev, qtmultimedia5-dev, libkysdk-systime-dev, + libkysdk-qtwidgets-dev, + libkysdk-diagnostics-dev, libkysdk-waylandhelper-dev, liblightdm-qt5-3-dev, libsystemd-dev, libssl-dev, libxrandr-dev, - libcharls-dev + libcharls-dev, + libukcc-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://www.github.com/ukui/ukui-screensaver diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch --- ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch 2025-02-13 20:26:40.000000000 +0800 @@ -0,0 +1,182 @@ +From: yangmin100 <yangmin@kylinos.cn> +Date: Fri, 15 Nov 2024 10:53:23 +0800 +Subject: =?utf-8?b?b2vkvb/nlKjnpL7ljLrniYjor63lvZU=?= + +--- + src/common/global_utils.h | 6 ++ + src/screensaver/CMakeLists.txt | 1 + + src/screensaver/language/screensaver-zh_CN-ok.ini | 121 ++++++++++++++++++++++ + src/screensaver/screensaver.cpp | 3 + + 4 files changed, 131 insertions(+) + create mode 100644 src/screensaver/language/screensaver-zh_CN-ok.ini + +diff --git a/src/common/global_utils.h b/src/common/global_utils.h +index 8bdaa61..425d4d4 100644 +--- a/src/common/global_utils.h ++++ b/src/common/global_utils.h +@@ -42,6 +42,12 @@ QString getHostCloudPlatform(); + + bool isCommunity(); + ++/** ++ * @brief isOpenkylin 是否为ok环境 ++ * @return true 是,否则不是 ++ */ ++bool isOpenkylin(); ++ + QString getDefaultFace(); + + void setFcitxExport(); +diff --git a/src/screensaver/CMakeLists.txt b/src/screensaver/CMakeLists.txt +index 194af1c..ada55ef 100644 +--- a/src/screensaver/CMakeLists.txt ++++ b/src/screensaver/CMakeLists.txt +@@ -172,6 +172,7 @@ install(FILES + language/screensaver-en_US.ini + language/screensaver-bo_CN.ini + language/screensaver-jd.ini ++ language/screensaver-zh_CN-ok.ini + DESTINATION share/ukui-screensaver/language) + + install(FILES +diff --git a/src/screensaver/language/screensaver-zh_CN-ok.ini b/src/screensaver/language/screensaver-zh_CN-ok.ini +new file mode 100644 +index 0000000..51b93e7 +--- /dev/null ++++ b/src/screensaver/language/screensaver-zh_CN-ok.ini +@@ -0,0 +1,121 @@ ++[1] ++FL=世上的事,只要肯用心去学, ++SL=没有一件是太晚的。 ++author=三毛《送你一匹马》 ++[2] ++OL=如果你是大河,何必在乎别人把你当成小溪。 ++author=汪国真 《如果》 ++[3] ++OL=世界上有不绝的风景,我有不老的心情。 ++author=汪国真《我喜欢出发》 ++[4] ++OL=人生如逆旅,我亦是行人。 ++author=苏轼《临江仙·送钱穆父》 ++[5] ++OL=行乐直须年少,尊前看取衰翁。 ++author=欧阳修《朝中措·送刘仲原甫出守维扬》 ++[6] ++OL=行到水穷处,坐看云起时。 ++author=王维《终南别业》 ++[7] ++OL=仰天大笑出门去,我辈岂是蓬蒿人。 ++author=李白《南陵别儿童入京》 ++[8] ++OL=天生我材必有用,千金散尽还复来。 ++author=李白《将进酒》 ++[9] ++OL=希君生羽翼,一化北溟鱼。 ++author=李白《江夏使君叔席上赠史郎中》 ++[10] ++OL=惟沉默是最高的轻蔑。 ++author=鲁迅《且介亭杂文附集》 ++[11] ++OL=虽偶有轻风细雨,但总归晴天朗照。 ++author=史铁生《记忆与印象》 ++[12] ++OL=不能走远路却有辽阔的心。 ++author=史铁生《我与地坛》 ++[13] ++OL=从卖气球的人那里,每个孩子牵走一个心愿。 ++author=北岛《代课》 ++[14] ++OL=要有最朴素的生活和最遥远的梦想 ++author=海子《枫》 ++[15] ++OL=雾打湿了我的双翼,可风却不容我再迟疑。 ++author=舒婷《双桅船》 ++[16] ++OL=拯救地球好累,虽然有些疲惫但我还是会。 ++author=《超人不会飞》 ++[17] ++OL=宁可一思进,莫在一思停。 ++author=电影《一代宗师》 ++[18] ++OL=让人类永远保持理智,确实是一件奢侈的事。 ++author=电影《流浪地球》 ++[19] ++FL=无论结果如何,人类的勇气和坚毅, ++SL=都被镌刻在星空下。 ++author=电影《流浪地球》 ++[20] ++OL=生活就像一盒巧克力,你不知道你的下一块口味是什么。 ++author=电影《阿甘正传》 ++[21] ++FL=也许我们这些聪明人,脑袋里能装的目标太多, ++SL=所以忘了执着。 ++author=电影《阿甘正传》 ++[22] ++FL=我并不是每次吃完饭就看电视,有时我边吃边看电视, ++SL=生活中有些改变会增加乐趣。 ++author=电影《加菲猫》 ++[23] ++OL=做人如果没梦想,那跟咸鱼有什么分别? ++author=电影《少林足球》 ++[24] ++FL=世界上有一种鸟是关不住的,因为它们的每一片羽毛都沾满了太阳的光辉。 ++SL=当它们飞走的时候,你会觉得把它关起来是一种罪恶。 ++author=电影《肖申克的救赎》 ++[25] ++FL=你每天都在做很多看起来毫无意义的决定, ++SL=但某天你的某个决定就能改变你一生。 ++author=电影《西雅图未眠夜》 ++[26] ++FL=把人类看做虫子的三体人似乎忘记了一个事实: ++SL=虫子从来没有被战胜过。 ++author=刘慈欣《三体》 ++[27] ++FL=在宇宙中,你再快都有比你更快的, ++SL=你再慢也有比你更慢的。 ++author=刘慈欣《三体》 ++[28] ++OL=人间风雨各处有,何处不是浪浪山? ++author=国漫《小妖怪的夏天》 ++[29] ++FL=我看到那些岁月如何奔驰, ++SL=挨过了冬季,便迎来了春天。 ++author=《瓦尔登湖》 ++[30] ++OL=保持热爱,奔赴山海。 ++author=佚名 ++[31] ++OL=别慌,月亮也正在大海某处迷茫。 ++author=佚名 ++[32] ++OL=当太阳升到最高点的时候,影子就不见了。 ++author=佚名 ++[33] ++OL=大直若屈,大巧若拙,大辩若讷。 ++author=《老子》 ++[34] ++OL=博学之,审问之,慎思之,明辨之,笃行之。 ++author=《礼记》 ++[35] ++OL=你要批评指点四周的风景,你首先要爬上屋顶。 ++author=歌德 ++[36] ++OL=只有流过血的手指,才能弹出世间的绝唱。 ++author=泰戈尔 ++[37] ++OL=他强任他强,清风拂山岗。 ++author=佚名 ++ +diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp +index 578fa3a..71e2f0a 100644 +--- a/src/screensaver/screensaver.cpp ++++ b/src/screensaver/screensaver.cpp +@@ -713,6 +713,9 @@ void Screensaver::setUpdateCenterWidget() + + // 不管系统语言,默认显示中文 + QString languageFilePath = languageDirPath + "screensaver-zh_CN.ini"; ++ if (isOpenkylin()) { ++ languageFilePath = languageDirPath + "screensaver-zh_CN-ok.ini"; ++ } + // QString languageFilePath=languageDirPath+"screensaver-"+lang+".ini"; + QString homeLanguageFilePath = homePath + "/.config/ukui/screensaver-" + lang + ".ini"; + QString jdLanguageFilePath = languageDirPath + "screensaver-jd" + ".ini"; diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch --- ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch 2025-02-13 20:26:40.000000000 +0800 @@ -0,0 +1,1812 @@ +From: yangmin100 <yangmin@kylinos.cn> +Date: Fri, 3 Jan 2025 14:42:13 +0800 +Subject: sysc codes from v11-2503 + +--- + src/common/configuration.cpp | 24 ------- + src/common/configuration.h | 3 - + src/common/utils.cpp | 3 + + src/dbusifs/kglobalaccelhelper.cpp | 13 ++-- + src/dbusifs/uniauthservice.cpp | 123 +++++++++++++++++++++++++++++++- + src/dbusifs/uniauthservice.h | 93 +++++++++++++++++++++++- + src/lock-backend/bioauthenticate.cpp | 31 ++++---- + src/lock-backend/bioauthenticate.h | 1 - + src/lock-backend/dbusupperinterface.cpp | 44 ++++++++---- + src/lock-backend/dbusupperinterface.h | 2 +- + src/lock-backend/lightdmhelper.cpp | 24 +++++-- + src/lock-backend/main.cpp | 3 + + src/lock-backend/switchuserutils.cpp | 9 +++ + src/lock-dialog/backenddbushelper.cpp | 3 +- + src/lock-dialog/backenddbushelper.h | 2 +- + src/lock-dialog/lockdialogmodel.cpp | 2 +- + src/lock-dialog/lockdialogmodel.h | 2 +- + src/lock-dialog/main.cpp | 30 +++++--- + src/screensaver/main.cpp | 3 + + src/screensaver/scconfiguration.cpp | 9 ++- + src/screensaver/screensaver.cpp | 47 ++++++------ + src/widgets/authdialog.cpp | 14 ++-- + src/widgets/authdialog.h | 3 +- + src/widgets/blockwidget.cpp | 41 +++++++++-- + src/widgets/blockwidget.h | 1 + + src/widgets/fullbackgroundwidget.cpp | 41 +++++++---- + src/widgets/lockwidget.cpp | 120 +++++++++++++++++++++---------- + src/widgets/lockwidget.h | 9 ++- + src/widgets/loginoptionswidget.cpp | 27 ++++--- + src/widgets/loginoptionswidget.h | 3 +- + src/widgets/mpriswidget.cpp | 18 ++++- + src/widgets/mpriswidget.h | 7 ++ + src/widgets/powerlistwidget.cpp | 18 +++++ + src/widgets/powerlistwidget.h | 3 + + src/widgets/screensaverwidget.cpp | 2 +- + 35 files changed, 586 insertions(+), 192 deletions(-) + +diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp +index 85a80d9..9db84f7 100644 +--- a/src/common/configuration.cpp ++++ b/src/common/configuration.cpp +@@ -90,30 +90,6 @@ bool Configuration::hasValue(const QString &key) + return value; + } + +-QString Configuration::getLastLoginUser() +-{ +- recordSettings->beginGroup("Greeter"); +- QString lastLoginUser = recordSettings->value("lastLoginUser").toString(); +- recordSettings->endGroup(); +- return lastLoginUser; +-} +- +-void Configuration::saveLastLoginUser(const QString &userRealName) +-{ +- recordSettings->beginGroup("Greeter"); +- recordSettings->setValue("lastLoginUser", userRealName); +- recordSettings->endGroup(); +- recordSettings->sync(); +-} +- +-void Configuration::saveLastLoginUser1(const QString &userRealName) +-{ +- recordSettings->beginGroup("Greeter"); +- recordSettings->setValue("lastLoginUser1", userRealName); +- recordSettings->endGroup(); +- recordSettings->sync(); +-} +- + bool Configuration::getLastNumLock() + { + recordSettings->beginGroup("Greeter"); +diff --git a/src/common/configuration.h b/src/common/configuration.h +index dc01545..ba9142e 100644 +--- a/src/common/configuration.h ++++ b/src/common/configuration.h +@@ -38,9 +38,6 @@ public: + bool hasValue(const QString &); + + void getCurrentUser(const QString userName); +- QString getLastLoginUser(); +- void saveLastLoginUser(const QString &); +- void saveLastLoginUser1(const QString &); + bool getLastNumLock(); + void saveLastNumLock(bool value); + int getRootBackgroundOption(QString userName); +diff --git a/src/common/utils.cpp b/src/common/utils.cpp +index 22ddf60..c7641c7 100644 +--- a/src/common/utils.cpp ++++ b/src/common/utils.cpp +@@ -108,6 +108,9 @@ bool checkCapsLockState() + } + } + ++ if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { ++ return false; ++ } + bool capsState = false; + unsigned int n; + XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &n); +diff --git a/src/dbusifs/kglobalaccelhelper.cpp b/src/dbusifs/kglobalaccelhelper.cpp +index 1094cc6..070b404 100644 +--- a/src/dbusifs/kglobalaccelhelper.cpp ++++ b/src/dbusifs/kglobalaccelhelper.cpp +@@ -36,10 +36,15 @@ KglobalAccelHelper::~KglobalAccelHelper() {} + + bool KglobalAccelHelper::blockShortcut(bool val) + { +- QDBusMessage result = m_kglobalInterface->call("blockGlobalShortcuts", val); +- if (result.type() == QDBusMessage::ErrorMessage) { +- qWarning() << "blockShortcut error:" << result.errorMessage(); ++ qDebug()<<"m_kglobalInterface isvalid:"<<m_kglobalInterface->isValid(); ++ if (m_kglobalInterface->isValid()) { ++ QDBusMessage result = m_kglobalInterface->call("blockGlobalShortcuts", val); ++ if (result.type() == QDBusMessage::ErrorMessage) { ++ qWarning() << "blockShortcut error:" << result.errorMessage(); ++ return false; ++ } ++ return true; ++ } else { + return false; + } +- return true; + } +diff --git a/src/dbusifs/uniauthservice.cpp b/src/dbusifs/uniauthservice.cpp +index 90b165b..1657b24 100644 +--- a/src/dbusifs/uniauthservice.cpp ++++ b/src/dbusifs/uniauthservice.cpp +@@ -21,11 +21,38 @@ + #include "definetypes.h" + #include "freedesktophelper.h" + ++/* For the type WillLoginUserInfo */ ++QDBusArgument &operator<<(QDBusArgument &argument, const WillLoginUserInfo &willLoginUserInfo) ++{ ++ argument.beginStructure(); ++ argument << willLoginUserInfo.strUserName << willLoginUserInfo.isOneKeyLogin; ++ argument.endStructure(); ++ return argument; ++} ++ ++const QDBusArgument &operator>>(const QDBusArgument &argument, WillLoginUserInfo &willLoginUserInfo) ++{ ++ argument.beginStructure(); ++ argument >> willLoginUserInfo.strUserName >> willLoginUserInfo.isOneKeyLogin; ++ argument.endStructure(); ++ return argument; ++} ++ ++QDebug operator<<(QDebug stream, const WillLoginUserInfo &willLoginUserInfo) ++{ ++ stream << "WillLogUser [" << willLoginUserInfo.strUserName << willLoginUserInfo.isOneKeyLogin << "]"; ++ return stream; ++} ++ ++UniAuthService *UniAuthService::m_instance = nullptr; ++UniAuthService::MemCollector UniAuthService::m_memCollector; + UniAuthService::UniAuthService(QObject *parent) + : QDBusAbstractInterface( + UNIAUTH_DBUS_SERVICE, UNIAUTH_DBUS_PATH, UNIAUTH_DBUS_INTERFACE, QDBusConnection::systemBus(), parent) + , m_isActivatable(false) + { ++ qRegisterMetaType<WillLoginUserInfo>("WillLoginUserInfo"); ++ qDBusRegisterMetaType<WillLoginUserInfo>(); + setTimeout(2147483647); + FreedesktopHelper *systemFdHelper = new FreedesktopHelper(false); + if (systemFdHelper) { +@@ -36,6 +63,14 @@ UniAuthService::UniAuthService(QObject *parent) + } + } + ++UniAuthService *UniAuthService::instance(QObject *parent) ++{ ++ if (!m_instance) { ++ m_instance = new UniAuthService(parent); ++ } ++ return m_instance; ++} ++ + // 设置默认设备 + void UniAuthService::setDefaultDevice(int bioDevType, QString deviceName) + { +@@ -78,7 +113,7 @@ QStringList UniAuthService::getAllDefaultDevice(QString userName) + return listDefDevices; + } + +-//生物特征开关接口 ++// 生物特征开关接口 + bool UniAuthService::getBioAuthStatus(QString userName, int bioAuthType) + { + QDBusMessage bioResult = call(QStringLiteral("getBioAuthStatus"), userName, bioAuthType); +@@ -236,3 +271,89 @@ int UniAuthService::getFTimeoutTimes() + return 1; + } + } ++ ++void UniAuthService::SwitchToUser(QString strUserName) ++{ ++ QDBusReply<int> reply = call(QStringLiteral("SwitchToUser"), strUserName); ++ if (!reply.isValid()) { ++ qWarning() << "SwitchToUser error:" << reply.error(); ++ return; ++ } ++ return; ++} ++ ++void UniAuthService::SwitchToGreeterUser(QString strUserName) ++{ ++ QDBusReply<int> reply = call(QStringLiteral("SwitchToGreeterUser"), strUserName); ++ if (!reply.isValid()) { ++ qWarning() << "SwitchToGreeterUser error:" << reply.error(); ++ return; ++ } ++ return; ++} ++ ++WillLoginUserInfo UniAuthService::getWillSwitchUser() ++{ ++ WillLoginUserInfo willLoginUserInfo; ++ QDBusMessage result = call(QStringLiteral("getWillSwitchUser")); ++ if (result.type() == QDBusMessage::ErrorMessage) { ++ qWarning() << "getWillSwitchUser error:" << result.errorMessage(); ++ return willLoginUserInfo; ++ } ++ if (result.arguments().size() > 0) { ++ QDBusArgument argInfo = result.arguments().at(0).value<QDBusArgument>(); ++ argInfo >> willLoginUserInfo; ++ } ++ qDebug() << "getUserInfo:" << willLoginUserInfo; ++ return willLoginUserInfo; ++} ++ ++bool UniAuthService::isUserNameValid(QString strUserName) ++{ ++ struct passwd *userInfo = nullptr; ++ userInfo = getpwnam(strUserName.toLatin1().data()); ++ if (userInfo) { ++ return true; ++ } ++ return false; ++} ++ ++int UniAuthService::SaveLastLoginUser(QString strUserName) ++{ ++ QDBusReply<int> reply = call(QStringLiteral("SaveLastLoginUser"), strUserName); ++ if (!reply.isValid()) { ++ qWarning() << "SaveLastLoginUser error:" << reply.error(); ++ return -1; ++ } ++ return reply.value(); ++} ++ ++QString UniAuthService::GetLastLoginUser() ++{ ++ QDBusReply<QString> reply = call(QStringLiteral("GetLastLoginUser")); ++ if (!reply.isValid()) { ++ qWarning() << "GetLastLoginUser error:" << reply.error(); ++ return QString(""); ++ } ++ return reply.value(); ++} ++ ++int UniAuthService::SaveQuickLoginUser(QString strUserName) ++{ ++ QDBusReply<int> reply = call(QStringLiteral("SaveQuickLoginUser"), strUserName); ++ if (!reply.isValid()) { ++ qWarning() << "SaveQuickLoginUser error:" << reply.error(); ++ return -1; ++ } ++ return reply.value(); ++} ++ ++QString UniAuthService::GetQuickLoginUser() ++{ ++ QDBusReply<QString> reply = call(QStringLiteral("GetQuickLoginUser")); ++ if (!reply.isValid()) { ++ qWarning() << "GetQuickLoginUser error:" << reply.error(); ++ return QString(""); ++ } ++ return reply.value(); ++} +diff --git a/src/dbusifs/uniauthservice.h b/src/dbusifs/uniauthservice.h +index ef7d1c0..2599c95 100644 +--- a/src/dbusifs/uniauthservice.h ++++ b/src/dbusifs/uniauthservice.h +@@ -32,12 +32,36 @@ enum authEnableType + ENABLETYPE_LOGIN, // 暂保留 + }; + ++/** ++ * @brief 用户信息 ++ */ ++struct WillLoginUserInfo ++{ ++ QString strUserName = ""; ++ bool isOneKeyLogin = false; ++}; ++ ++QDBusArgument &operator <<(QDBusArgument &arg, const WillLoginUserInfo &willLoginUserInfo); ++const QDBusArgument &operator >>(const QDBusArgument &arg, WillLoginUserInfo &willLoginUserInfo); ++QDebug operator <<(QDebug stream, const WillLoginUserInfo &willLoginUserInfo); ++ ++Q_DECLARE_METATYPE(WillLoginUserInfo) ++ + class UniAuthService : public QDBusAbstractInterface + { + Q_OBJECT +-public: ++private: + explicit UniAuthService(QObject *parent = nullptr); + ++public: ++ /** ++ * @brief 单实例 ++ * ++ * @param parent 父指针 ++ * @return UniAuthService 单实例对象指针 ++ */ ++ static UniAuthService *instance(QObject *parent = nullptr); ++ + public Q_SLOTS: + // 设置默认设备 + void setDefaultDevice(int bioDevType, QString deviceName); +@@ -64,6 +88,53 @@ public Q_SLOTS: + bool getHiddenSwitchButton(); + // 获取人脸超时停用次数 + int getFTimeoutTimes(); ++ /** ++ * @brief 用户名是否有效 ++ * ++ * @param strUserName 用户名 ++ * @return bool true 有效,否则 无效 ++ */ ++ bool isUserNameValid(QString strUserName); ++ /** ++ * @brief 一键切换并登录用户 ++ * ++ * @param strUserName 用户名 ++ */ ++ void SwitchToUser(QString strUserName); ++ /** ++ * @brief 切换到登录用户 ++ * ++ * @param strUserName 用户名 ++ */ ++ void SwitchToGreeterUser(QString strUserName); ++ /** ++ * @brief 将要登录的用户信息 ++ * ++ * @return WillLoginUserInfo 用户信息 ++ */ ++ WillLoginUserInfo getWillSwitchUser(); ++ /** ++ * @brief SaveLastLoginUser 记录上一次登录成功的用户 ++ * @param strUserName 用户名 ++ * @return 0 成功,其他失败 ++ */ ++ int SaveLastLoginUser(QString strUserName); ++ /** ++ * @brief GetLastLoginUser 获取上一次登录的用户 ++ * @return 用户名 ++ */ ++ QString GetLastLoginUser(); ++ /** ++ * @brief SaveQuickLoginUser 保存下次快速登录的用户 ++ * @param strUserName 用户名 ++ * @return 0 成功,其他失败 ++ */ ++ int SaveQuickLoginUser(QString strUserName); ++ /** ++ * @brief GetQuickLoginUser 获取快速登录的用户名 ++ * @return 用户名 ++ */ ++ QString GetQuickLoginUser(); + + public: + bool isActivatable(); +@@ -73,6 +144,26 @@ Q_SIGNALS: + void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName); + //开关状态改变 + void bioAuthStatusChanged(QString userName, int type, bool status); ++ /** ++ * @brief 将要登录的用户名改变 ++ * ++ * @param strUserName 新用户名(需对空串异常处理) ++ * @param isOneKeyLogin 是否需要一键登录 ++ */ ++ void userChanged(WillLoginUserInfo willLoginUser); ++ ++private: ++ class MemCollector{ ++ public: ++ ~MemCollector(){ ++ if (UniAuthService::instance()) { ++ delete UniAuthService::instance(); ++ UniAuthService::m_instance = nullptr; ++ } ++ } ++ }; ++ static UniAuthService *m_instance; /** 统一认证配置服务单实例指针 */ ++ static MemCollector m_memCollector; + + private: + bool m_isActivatable; +diff --git a/src/lock-backend/bioauthenticate.cpp b/src/lock-backend/bioauthenticate.cpp +index e072f56..93f1804 100644 +--- a/src/lock-backend/bioauthenticate.cpp ++++ b/src/lock-backend/bioauthenticate.cpp +@@ -24,14 +24,11 @@ + #include "giodbus.h" + + BioAuthenticate::BioAuthenticate(QObject *parent) +- : QObject(parent) +- , m_systemFdHelper(new FreedesktopHelper(false, this)) +- , m_uniauthService(new UniAuthService(this)) +- , m_bioTimer(nullptr) ++ : QObject(parent), m_systemFdHelper(new FreedesktopHelper(false, this)), m_bioTimer(nullptr) + { + m_bioauthState = BIOAUTH_IDLE; + m_deviceInfo.id = -1; +- m_maxFailedTimes = m_uniauthService->getMaxFailedTimes(); ++ m_maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes(); + m_listPriority.clear(); + m_listPriority.push_back(BioT_Face); + m_listPriority.push_back(BioT_FingerPrint); +@@ -130,9 +127,9 @@ void BioAuthenticate::onServiceStatusChanged(const QString &strService, bool bAc + bool BioAuthenticate::getBioAuthEnable(QString strUserName, int nType) + { + bool isEnable = false; +- isEnable = m_uniauthService->getBioAuthStatus(strUserName, ENABLETYPE_BIO); ++ isEnable = UniAuthService::instance()->getBioAuthStatus(strUserName, ENABLETYPE_BIO); + if (isEnable) { +- isEnable = m_uniauthService->getBioAuthStatus(strUserName, nType); ++ isEnable = UniAuthService::instance()->getBioAuthStatus(strUserName, nType); + } + return isEnable; + } +@@ -157,9 +154,9 @@ void BioAuthenticate::checkAvailableBioInfo(int nUid) + if (pwdInfo) { + int nAuthType = (pwdInfo->pw_name == getenv("USER")) ? ENABLETYPE_SAVER : ENABLETYPE_GREETER; + bool isAuthEnable = getBioAuthEnable(pwdInfo->pw_name, nAuthType); +- bool isQRCodeEnable = m_uniauthService->getQRCodeEnable(); ++ bool isQRCodeEnable = UniAuthService::instance()->getQRCodeEnable(); + DeviceList deviceList = m_biometricHelper->GetDevList(); +- QStringList listDefDevices = m_uniauthService->getAllDefaultDevice(pwdInfo->pw_name); ++ QStringList listDefDevices = UniAuthService::instance()->getAllDefaultDevice(pwdInfo->pw_name); + qDebug() << "BeginGetFeature------!"; + FeatureMap mapFeatures = m_biometricHelper->GetUserFeatures(nUid); + qDebug() << nUid << ",count:" << mapFeatures.size(); +@@ -212,7 +209,7 @@ void BioAuthenticate::onBioDeviceChanged(int drvid, int action, int devNum) + Q_UNUSED(devNum); + switch (action) { + case ACTION_ATTACHED: { +- //插入设备后,需要更新设备列表 ++ // 插入设备后,需要更新设备列表 + clearBioData(); + QMap<int, DeviceMap>::iterator itUserDev = m_mapDevices.begin(); + for (; itUserDev != m_mapDevices.end(); itUserDev++) { +@@ -375,11 +372,11 @@ void BioAuthenticate::onIdentifyComplete(QDBusPendingCallWatcher *watcher) + } else if (result == DBUS_RESULT_NOTMATCH) { // 特征识别不匹配 + qDebug() << "Identify failed"; + onBioAuthComplete(false, 2); +- } else if (result == DBUS_RESULT_ERROR) { //识别发生错误 ++ } else if (result == DBUS_RESULT_ERROR) { // 识别发生错误 + StatusReslut ret = m_biometricHelper->UpdateStatus(m_deviceInfo.id); + qDebug() << "StatusReslut:" << ret.result << "," << ret.enable << "," << ret.devNum << "," << ret.devStatus + << "," << ret.opsStatus << "," << ret.notifyMessageId; +- //识别操作超时 304/404 认证超时;8 网络错误; ++ // 识别操作超时 304/404 认证超时;8 网络错误; + if (ret.result == 0) { + if (ret.opsStatus == OPS_IDENTIFY_TIMEOUT || ret.opsStatus == OPS_VERIFY_TIMEOUT + || ret.opsStatus == 8) { // 304认证超时, 8网络异常 +@@ -460,7 +457,7 @@ void BioAuthenticate::onBioAuthComplete(bool isSuccess, int nError) + startBioAuth(10000); + } else if (m_deviceInfo.deviceType == LOGINOPT_TYPE_FACE && nError == 1) { + m_fTimeoutTimes += 1; +- if (m_fTimeoutTimes == m_uniauthService->getFTimeoutTimes()) { ++ if (m_fTimeoutTimes == UniAuthService::instance()->getFTimeoutTimes()) { + m_fTimeoutTimes = 0; + nError = 6; + } else { +@@ -524,8 +521,8 @@ void BioAuthenticate::startBioAuth(unsigned uTimeout) + QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName, int bioType) + { + QString defaultDeviceName = ""; +- if (m_uniauthService && m_uniauthService->isActivatable()) { +- QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); ++ if (UniAuthService::instance()->isActivatable()) { ++ QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType); + if (!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(nUid, strDeviceName); + if (pDeviceInfo) { +@@ -539,9 +536,9 @@ QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName, int bio + QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName) + { + QString defaultDeviceName = ""; +- if (m_uniauthService && m_uniauthService->isActivatable()) { ++ if (UniAuthService::instance()->isActivatable()) { + for (auto bioType : m_listPriority) { +- QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); ++ QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType); + if (!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(nUid, strDeviceName); + if (pDeviceInfo) { +diff --git a/src/lock-backend/bioauthenticate.h b/src/lock-backend/bioauthenticate.h +index 9f7378b..c26e533 100644 +--- a/src/lock-backend/bioauthenticate.h ++++ b/src/lock-backend/bioauthenticate.h +@@ -82,7 +82,6 @@ private: + BiometricHelper *m_biometricHelper = nullptr; + FreedesktopHelper *m_systemFdHelper = nullptr; + QMap<int, DeviceMap> m_mapDevices; // 用户可用的设备 +- UniAuthService *m_uniauthService = nullptr; + DeviceInfo m_deviceInfo; + BIOAUTH_STATE m_bioauthState; + int m_fdFrame = -1; +diff --git a/src/lock-backend/dbusupperinterface.cpp b/src/lock-backend/dbusupperinterface.cpp +index 217bdf9..db209a7 100644 +--- a/src/lock-backend/dbusupperinterface.cpp ++++ b/src/lock-backend/dbusupperinterface.cpp +@@ -43,6 +43,7 @@ + #include "kglobalaccelhelper.h" + #include "personalizeddata.h" + #include "libinputswitchevent.h" ++#include "uniauthservice.h" + + #define CONFIG_FILE "/usr/share/ukui-greeter/ukui-greeter.conf" + +@@ -306,7 +307,7 @@ void DbusUpperInterface::SessionTools() + message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "SecondRunParam"); + message << "CmdSessionTools"; + QDBusConnection::sessionBus().send(message); +- emitLockState(true); ++ emitLockState(false, true); + return; + } + m_bLockState = false; +@@ -314,7 +315,7 @@ void DbusUpperInterface::SessionTools() + qDebug() << cmd; + + m_procLockDialog.start(cmd); +- emitLockState(true); ++ emitLockState(false, true); + } + + void DbusUpperInterface::AppBlockWindow(QString actionType) +@@ -345,7 +346,7 @@ void DbusUpperInterface::AppBlockWindow(QString actionType) + else + return; + QDBusConnection::sessionBus().send(message); +- emitLockState(false); ++ emitLockState(false, true); + return; + } + if (actionType != "Restart" && actionType != "Shutdown" && actionType != "Suspend" && actionType != "Hibernate" +@@ -357,7 +358,7 @@ void DbusUpperInterface::AppBlockWindow(QString actionType) + qDebug() << cmd; + + m_procLockDialog.start(cmd); +- emitLockState(false); ++ emitLockState(false, true); + } + + void DbusUpperInterface::MultiUserBlockWindow(QString actionType) +@@ -372,7 +373,7 @@ void DbusUpperInterface::MultiUserBlockWindow(QString actionType) + else + return; + QDBusConnection::sessionBus().send(message); +- emitLockState(false); ++ emitLockState(false, true); + return; + } + if (actionType != "Restart" && actionType != "Shutdown") +@@ -383,7 +384,7 @@ void DbusUpperInterface::MultiUserBlockWindow(QString actionType) + qDebug() << cmd; + + m_procLockDialog.start(cmd); +- emitLockState(false); ++ emitLockState(false, true); + } + + void DbusUpperInterface::Suspend() +@@ -624,23 +625,25 @@ bool DbusUpperInterface::checkScreenDialogRunning() + return isRunning; + } + +-void DbusUpperInterface::emitLockState(bool val) ++void DbusUpperInterface::emitLockState(bool val, bool isSessionTools) + { + qDebug() << "emitLockState state = " << val; + + if (val != m_bBlockShortcutState) { + m_kglobalHelper->blockShortcut(val); + m_bBlockShortcutState = val; +- qDebug() << " block all shortcut " << "blockShortcut states = " << m_bBlockShortcutState; ++ qDebug() << " block all shortcut " ++ << "blockShortcut states = " << m_bBlockShortcutState; + } + + QDBusMessage message; +- if (val) { ++ if (val && !isSessionTools) { + message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "lock"); +- } else { ++ QDBusConnection::sessionBus().send(message); ++ } else if (!val && !isSessionTools) { + message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "unlock"); ++ QDBusConnection::sessionBus().send(message); + } +- QDBusConnection::sessionBus().send(message); + } + + QString DbusUpperInterface::GetInformation(QString strJson) +@@ -1091,8 +1094,18 @@ QString DbusUpperInterface::GetDefaultAuthUser() + strUserName = getenv("USER"); + } else { + // 获取lightdm传过来的被选中的用户 +- QString selectedUser = m_lightDmHelper->selectUserHint(); +- if (!selectedUser.isEmpty()) { ++ WillLoginUserInfo willSwitchUser = UniAuthService::instance()->getWillSwitchUser(); ++ QString selectedUser = ""; ++ if (willSwitchUser.strUserName.isEmpty() ++ || !UniAuthService::instance()->isUserNameValid(willSwitchUser.strUserName)) { ++ qDebug() << "WillSwitchUser is NULL or invalid:" << willSwitchUser.strUserName; ++ selectedUser = m_lightDmHelper->selectUserHint(); ++ } ++ UniAuthService::instance()->SwitchToGreeterUser(""); ++ if (!willSwitchUser.strUserName.isEmpty()) { ++ strUserName = willSwitchUser.strUserName; ++ qDebug() << "WillSwitchUser:" << strUserName; ++ } else if (!selectedUser.isEmpty()) { + qDebug() << "SelectUserHint: " << selectedUser; + if (m_lightDmHelper->findUserByName(selectedUser)) { + strUserName = selectedUser; +@@ -1108,7 +1121,7 @@ QString DbusUpperInterface::GetDefaultAuthUser() + } else if (m_lightDmHelper->getUsersInfo().count() == 1) { // 如果只有一个用户,默认选中 + strUserName = m_lightDmHelper->getUsersInfo()[0]->name(); + } else { +- QString lastLoginUser = m_config->getLastLoginUser(); ++ QString lastLoginUser = UniAuthService::instance()->GetLastLoginUser(); + if (m_lightDmHelper->findUserByName(lastLoginUser)) { + strUserName = lastLoginUser; + } else { +@@ -2624,9 +2637,10 @@ bool DbusUpperInterface::lockStateChanged(const QJsonObject &objInfo) + { + int nRet = -1; + bool state = objInfo.value("Content").toBool(); ++ bool isSessionTools = objInfo.value("SessionTools").toBool(); + if (lockState != state) { + lockState = state; +- emitLockState(state); ++ emitLockState(state, isSessionTools); + } + return lockState; + } +diff --git a/src/lock-backend/dbusupperinterface.h b/src/lock-backend/dbusupperinterface.h +index 67302bb..2797db9 100644 +--- a/src/lock-backend/dbusupperinterface.h ++++ b/src/lock-backend/dbusupperinterface.h +@@ -68,7 +68,7 @@ public: + + public: + bool checkScreenDialogRunning(); +- void emitLockState(bool val); ++ void emitLockState(bool val, bool isSessionTools = false); + void LockStartupMode(); + /** + * @brief 获取黑色屏保状态(沿用) +diff --git a/src/lock-backend/lightdmhelper.cpp b/src/lock-backend/lightdmhelper.cpp +index 8444de5..c599ac8 100644 +--- a/src/lock-backend/lightdmhelper.cpp ++++ b/src/lock-backend/lightdmhelper.cpp +@@ -20,13 +20,19 @@ + #include <QLightDM/Greeter> + #include <QFileInfo> + #include "securityuser.h" ++#include "global_utils.h" + #include <pwd.h> + #include "proxymodel.h" + #include "accountshelper.h" + #include "definetypes.h" ++#include "uniauthservice.h" + #include <QDBusArgument> + #include <QDBusMessage> + #include <QVariantMap> ++#ifdef WITHKYSEC ++#include <kysec/libkysec.h> ++#include <kysec/status.h> ++#endif + + LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent) + : QLightDM::Greeter(parent) +@@ -39,7 +45,7 @@ LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *confi + , m_mapUsers(new QMap<QString, UserInfoPtr>()) + , m_dbusIfsLDM(nullptr) + { +- //连接到lightdm ++ // 连接到lightdm + if (!connectToDaemonSync()) { + qDebug() << "connect to Daemon failed"; + exit(1); +@@ -66,6 +72,9 @@ void LightDMHelper::initData() + m_isShowManualLogin = true; + } + updateUsersInfo(); ++ if (isGreeterMode() && UniAuthService::instance()) { ++ UniAuthService::instance()->SaveQuickLoginUser(""); ++ } + } + + bool LightDMHelper::setSession(const QString &session) +@@ -109,9 +118,16 @@ int LightDMHelper::getLoginUserCount() + void LightDMHelper::startSession() + { + if (isAuthenticated()) { +- if (m_configuration) { +- m_configuration->saveLastLoginUser(m_strCurUserName); +- m_configuration->saveLastLoginUser1(m_strCurUserName); ++ if (UniAuthService::instance()) { ++ UniAuthService::instance()->SaveLastLoginUser(m_strCurUserName); ++// 三权分立不保存秒级登录用户信息 ++#ifdef WITHKYSEC ++ if (kysec_is_disabled() || !kysec_get_3adm_status()) { ++#endif ++ UniAuthService::instance()->SaveQuickLoginUser(m_strCurUserName); ++#ifdef WITHKYSEC ++ } ++#endif + } + Q_EMIT authenticationSucess(m_strCurUserName); + } +diff --git a/src/lock-backend/main.cpp b/src/lock-backend/main.cpp +index 27916bc..cd35943 100644 +--- a/src/lock-backend/main.cpp ++++ b/src/lock-backend/main.cpp +@@ -24,6 +24,7 @@ + #include <signal.h> + #include <unistd.h> + #include <sys/wait.h> ++#include <sys/prctl.h> + #include <stdio.h> + #include <ukui-log4qt.h> + #include "qtsinglecoreapplication.h" +@@ -51,6 +52,8 @@ int main(int argc, char *argv[]) + return 0; + } + qInfo()<<"ukui screensaver backend Started!!"; ++ // 会话管理器退出时,锁屏后端也退出 ++ prctl(PR_SET_PDEATHSIG, SIGKILL); + //命令行参数解析 + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", "Backend for the ukui ScreenSaver.")); +diff --git a/src/lock-backend/switchuserutils.cpp b/src/lock-backend/switchuserutils.cpp +index 27d7de1..7dc55f9 100644 +--- a/src/lock-backend/switchuserutils.cpp ++++ b/src/lock-backend/switchuserutils.cpp +@@ -277,11 +277,20 @@ int SwitchUserUtils::SwitchToUserSession(QString seatPath, UserDisplayIfInfo &to + return 0; + } else if (!toUDII.strUserName.isEmpty()) { + if (!isGreeterMode()) { ++ // 切换到免密登录用户会直接登录桌面,需要先展示“登录”按钮 ++#if 0 + QDBusMessage result = ifaceDM.call("SwitchToUser", toUDII.strUserName, toUDII.strSessionPath); + if (result.type() == QDBusMessage::ErrorMessage) { + qWarning() << "SwitchUser SwitchToUser failed:" << result.errorMessage(); + return 2; + } ++#else ++ QDBusMessage result = ifaceDM.call("SwitchToGreeter"); ++ if (result.type() == QDBusMessage::ErrorMessage) { ++ qWarning() << "SwitchUser SwitchToGreeter failed:" << result.errorMessage(); ++ return 2; ++ } ++#endif + } else { + return 4; + } +diff --git a/src/lock-dialog/backenddbushelper.cpp b/src/lock-dialog/backenddbushelper.cpp +index 16c655b..eb6ff0e 100644 +--- a/src/lock-dialog/backenddbushelper.cpp ++++ b/src/lock-dialog/backenddbushelper.cpp +@@ -358,11 +358,12 @@ bool BackendDbusHelper::setCurrentSession(QString strSession) + return true; + } + +-bool BackendDbusHelper::lockStateChanged(bool isVisible) ++bool BackendDbusHelper::lockStateChanged(bool isVisible, bool isSessionTools) + { + QJsonObject jsonCmd; + jsonCmd["CmdId"] = LOCK_CMD_ID_LOCK_STATE_CHANGED; + jsonCmd["Content"] = isVisible; ++ jsonCmd["SessionTools"] = isSessionTools; + QDBusPendingReply<int> reply = SetInformation(QString(QJsonDocument(jsonCmd).toJson())); + if (reply.isError()) { + qWarning() << "lockStateChanged error: " << reply.error().message(); +diff --git a/src/lock-dialog/backenddbushelper.h b/src/lock-dialog/backenddbushelper.h +index 3bac8b9..426ab68 100644 +--- a/src/lock-dialog/backenddbushelper.h ++++ b/src/lock-dialog/backenddbushelper.h +@@ -148,7 +148,7 @@ public Q_SLOTS: + bool setCurrentUser(QString strUserName); + int switchToUser(QString strUserName); + bool setCurrentSession(QString strSession); +- bool lockStateChanged(bool isVisible); ++ bool lockStateChanged(bool isVisible, bool isSessionTools); + void startSession(); + + void pamAuthenticate(QString strUserName); +diff --git a/src/lock-dialog/lockdialogmodel.cpp b/src/lock-dialog/lockdialogmodel.cpp +index 3802e38..e0bcf16 100644 +--- a/src/lock-dialog/lockdialogmodel.cpp ++++ b/src/lock-dialog/lockdialogmodel.cpp +@@ -29,7 +29,7 @@ + #include <pwd.h> + + LockDialogModel::LockDialogModel(QObject *parent) +- : QObject(parent), m_isUseWayland(QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive)) ++ : QObject(parent), m_isUseWayland(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") + { + } + +diff --git a/src/lock-dialog/lockdialogmodel.h b/src/lock-dialog/lockdialogmodel.h +index 72abc20..8db3e16 100644 +--- a/src/lock-dialog/lockdialogmodel.h ++++ b/src/lock-dialog/lockdialogmodel.h +@@ -512,7 +512,7 @@ Q_SIGNALS: + + void agreementInfoChanged(); + +- void lockStateChanged(bool isVisible); ++ void lockStateChanged(bool isVisible, bool isSessionTools); + + void lidstateChanged(const QString &lidstate); + +diff --git a/src/lock-dialog/main.cpp b/src/lock-dialog/main.cpp +index 06064be..2e75af6 100644 +--- a/src/lock-dialog/main.cpp ++++ b/src/lock-dialog/main.cpp +@@ -54,10 +54,6 @@ int main(int argc, char *argv[]) + initUkuiLog4qt("ukui-screensaver-dialog"); + // 重启或关机时不被session关掉 + qunsetenv("SESSION_MANAGER"); +- if (!isGreeterMode()) { +- // 试用模式不起锁屏 +- checkIslivecd(); +- } + + qputenv("QT_QPA_PLATFORMTHEME", QByteArray("ukui")); + +@@ -74,8 +70,9 @@ int main(int argc, char *argv[]) + LockDialogModel *lockDialogModel = new LockDialogModel(); + LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel); + +- if (isGreeterMode()) ++ if (isGreeterMode() && !lockDialogModel->isUseWayland()) { + DisplayService::instance(lockDialogModel)->setCurUserName(lockDialogModel->defaultUserName()); ++ } + + QString strDisplay = ""; + if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") { +@@ -85,6 +82,20 @@ int main(int argc, char *argv[]) + } + QString id = QString("ukui-screensaver-dialog" + strDisplay); + QtSingleApplication app(id, argc, argv); ++ ++ LockDialogModel::CommandLineArgs cmdArgs; ++ if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) { ++ return 0; ++ } ++ ++ if (!isGreeterMode()) { ++ // 需要判断参数是否是session-tools ++ if (!cmdArgs.isSessionTools) { ++ // 试用模式不起锁屏 ++ checkIslivecd(); ++ } ++ } ++ + if (app.isRunning()) { + QString strArguments = QApplication::arguments().join(","); + app.sendMessage(strArguments); +@@ -93,7 +104,9 @@ int main(int argc, char *argv[]) + qInfo() << "ukui screensaver dialog is running!"; + return EXIT_SUCCESS; + } +- setCursorCenter(); ++ if (!lockDialogModel->isUseWayland()) { ++ setCursorCenter(); ++ } + // 加载插件实例 + PluginsLoader *pluginsLoader = &PluginsLoader::instance(); + pluginsLoader->start(QThread::HighestPriority); +@@ -125,11 +138,6 @@ int main(int argc, char *argv[]) + loopTemp->exec(); + } + +- LockDialogModel::CommandLineArgs cmdArgs; +- +- if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) { +- return 0; +- } + QObject::connect( + &app, SIGNAL(messageReceived(const QString &)), lockDialogModel, SLOT(onRunningMessage(const QString &))); + +diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp +index 4190ec5..6b04da1 100644 +--- a/src/screensaver/main.cpp ++++ b/src/screensaver/main.cpp +@@ -31,6 +31,7 @@ + #include <sys/prctl.h> + #include <signal.h> + #include <syslog.h> ++#include <ukui-log4qt.h> + + #define WORKING_DIRECTORY "/usr/share/ukui-screensaver" + bool bControlFlg = false;//是否控制面板窗口 +@@ -42,6 +43,8 @@ int main(int argc, char *argv[]) + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + #endif + QApplication a(argc, argv); ++ ++ initUkuiLog4qt("ukui-screensaver-default"); + /* + prctl(PR_SET_PDEATHSIG, SIGHUP); + //加载翻译文件 +diff --git a/src/screensaver/scconfiguration.cpp b/src/screensaver/scconfiguration.cpp +index e2c2f91..105045a 100644 +--- a/src/screensaver/scconfiguration.cpp ++++ b/src/screensaver/scconfiguration.cpp +@@ -114,10 +114,15 @@ void SCConfiguration::onConfigurationChanged(QString key, QVariant value) + QString SCConfiguration::getDefaultBackground() + { + QString backgroundFile = m_helperBackendDbus->getLockScreenConf(KEY_BACKGROUND).toString(); +- if (ispicture(backgroundFile)) ++ if (ispicture(backgroundFile)) { + return backgroundFile; +- else ++ } else { ++ QString default_background_path = "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; ++ if (ispicture(default_background_path)) { ++ return default_background_path; ++ } + return DEFAULT_BACKGROUND_PATH; ++ } + } + + int SCConfiguration::getTimeType() +diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp +index 71e2f0a..ace6b38 100644 +--- a/src/screensaver/screensaver.cpp ++++ b/src/screensaver/screensaver.cpp +@@ -370,7 +370,7 @@ bool Screensaver::eventFilter(QObject *obj, QEvent *event) + } + } + #endif +- return false; ++ return QWidget::eventFilter(obj, event); + } + + void Screensaver::paintEvent(QPaintEvent *event) +@@ -539,23 +539,25 @@ void Screensaver::resizeEvent(QResizeEvent * /*event*/) + if (flag == 0) { + QList<QLabel *> labelList = this->findChildren<QLabel *>(); + for (int i = 0; i < labelList.count(); i++) { +- int fontsize = labelList.at(i)->font().pixelSize(); +- int fontpt = labelList.at(i)->font().pointSize(); +- if (fontsize > 0) { ++ if (labelList.at(i) != myPreviewLabel) { ++ int fontsize = labelList.at(i)->font().pixelSize(); ++ int fontpt = labelList.at(i)->font().pointSize(); ++ if (fontsize > 0) { + #ifdef USE_INTEL +- const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 3); ++ const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 3); + #else +- const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 4); ++ const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 4); + #endif +- labelList.at(i)->setStyleSheet(SheetStyle); +- } else { +- QFont font = labelList.at(i)->font(); ++ labelList.at(i)->setStyleSheet(SheetStyle); ++ } else { ++ QFont font = labelList.at(i)->font(); + #ifdef USE_INTEL +- font.setPointSize(fontpt / 3); ++ font.setPointSize(fontpt / 3); + #else +- font.setPointSize(fontpt / 4); ++ font.setPointSize(fontpt / 4); + #endif +- labelList.at(i)->setFont(font); ++ labelList.at(i)->setFont(font); ++ } + } + } + QList<QWidget *> childList = timeLayout->findChildren<QWidget *>(); +@@ -882,6 +884,17 @@ void Screensaver::initUI() + } + } + } ++ // V11上在窗口关闭时会收到一个leaveEvent(),控制面板关闭的时候new这个label,会导致控制面板关闭卡顿。 ++ if (!myPreviewLabel) { ++ myPreviewLabel = new QLabel(this); ++ myPreviewLabel->setFixedHeight(30); ++ myPreviewLabel->setMinimumWidth(54); ++ ++ // 设置样式 ++ myPreviewLabel->setStyleSheet("background-color: rgb(38,38,38); border-radius: 0px; color:white;"); ++ myPreviewLabel->setAlignment(Qt::AlignCenter); ++ myPreviewLabel->hide(); ++ } + #endif + } + +@@ -1136,16 +1149,6 @@ void Screensaver::setRandomText() + + void Screensaver::setPreviewText(bool bVisible) + { +- if (!myPreviewLabel) { +- myPreviewLabel = new QLabel(this); +- myPreviewLabel->setFixedHeight(30); +- myPreviewLabel->setMinimumWidth(54); +- +- // 设置样式 +- myPreviewLabel->setStyleSheet("background-color: rgb(38,38,38); border-radius: 0px; color:white;"); +- myPreviewLabel->setAlignment(Qt::AlignCenter); +- } +- + myPreviewLabel->setText(m_strPreViewTrans); + myPreviewLabel->adjustSize(); + +diff --git a/src/widgets/authdialog.cpp b/src/widgets/authdialog.cpp +index 4a2b002..62c9b77 100644 +--- a/src/widgets/authdialog.cpp ++++ b/src/widgets/authdialog.cpp +@@ -55,7 +55,6 @@ AuthDialog::AuthDialog(LockDialogModel *model, UserInfoPtr userInfo, QWidget *pa + , m_isLockingFlg(false) + , m_isInputPasswd(false) + , m_curUserInfo(userInfo) +- , m_uniauthService(new UniAuthService(this)) + , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this)) + { + initUI(); +@@ -950,8 +949,8 @@ void AuthDialog::onFirstLoginIdentifyComplete(QDBusPendingCallWatcher *watcher) + struct passwd *pwd; + pwd = getpwuid(authUid); + if (pwd && pwd->pw_name) { +- if (m_uniauthService && m_uniauthService->isActivatable()) { +- bool isEnable = m_uniauthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO); ++ if (UniAuthService::instance()->isActivatable()) { ++ bool isEnable = UniAuthService::instance()->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO); + if (isEnable == false) + return; + } +@@ -1499,7 +1498,7 @@ void AuthDialog::performBiometricAuth() + if (!m_biometricProxy) { + waitBiometricServiceStatus(); + m_biometricProxy = new BiometricHelper(this); +- maxFailedTimes = m_uniauthService->getMaxFailedTimes(); ++ maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes(); + } + + // 服务没启动,或者打开DBus连接出错 +@@ -1613,8 +1612,7 @@ void AuthDialog::initBiometricWidget() + } else { + QHBoxLayout *optsLayout = new QHBoxLayout(m_widgetLoginOpts); + optsLayout->setContentsMargins(0, 0, 0, 0); +- m_loginOpts +- = new LoginOptionsWidget(m_biometricProxy, m_curUserInfo->uid(), m_uniauthService, m_widgetLoginOpts); ++ m_loginOpts = new LoginOptionsWidget(m_biometricProxy, m_curUserInfo->uid(), m_widgetLoginOpts); + optsLayout->addWidget(m_loginOpts); + connect(m_loginOpts, &LoginOptionsWidget::authComplete, this, &AuthDialog::onBiometricAuthComplete); + connect(m_loginOpts, &LoginOptionsWidget::optionSelected, this, &AuthDialog::onDeviceChanged); +@@ -1910,7 +1908,7 @@ void AuthDialog::onBiometricAuthComplete(bool result, int nStatus) + startBioAuth(10000); + } else if (m_uCurLoginOptType == LOGINOPT_TYPE_FACE && nStatus == 1) { + m_fTimeoutTimes += 1; +- if (m_fTimeoutTimes == m_uniauthService->getFTimeoutTimes()) { ++ if (m_fTimeoutTimes == UniAuthService::instance()->getFTimeoutTimes()) { + m_fRetryButton->show(); + m_labelFace->hide(); + setLoginTypeTip( +@@ -1987,7 +1985,7 @@ void AuthDialog::onBiometricDbusChanged(bool bActive) + qDebug() << "OnDelay init biometric!!"; + if (!m_biometricProxy) { + m_biometricProxy = new BiometricHelper(this); +- maxFailedTimes = m_uniauthService->getMaxFailedTimes(); ++ maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes(); + } + + // 服务没启动,或者打开DBus连接出错 +diff --git a/src/widgets/authdialog.h b/src/widgets/authdialog.h +index 603ea8b..2b25f86 100644 +--- a/src/widgets/authdialog.h ++++ b/src/widgets/authdialog.h +@@ -26,7 +26,6 @@ + #include "biodefines.h" + #include "loginoptionswidget.h" + #include "pluginsloader.h" +-#include "statusbutton.h" + #include <QDateTime> + + class QLabel; +@@ -35,6 +34,7 @@ class QPushButton; + class IconEdit; + class LockDialogModel; + class BioButtonListWidget; ++class StatuButton; + class QTimer; + class SecurityQuestionAnswer; + +@@ -283,7 +283,6 @@ private: + + QPixmap m_waitingPixmap; + QTimer *w_timer = nullptr; +- UniAuthService *m_uniauthService = nullptr; + bool isLoadingUkey = false; + bool isPowerup = false; + QDBusInterface *bioService = nullptr; +diff --git a/src/widgets/blockwidget.cpp b/src/widgets/blockwidget.cpp +index 1a3afc0..99a6284 100644 +--- a/src/widgets/blockwidget.cpp ++++ b/src/widgets/blockwidget.cpp +@@ -137,8 +137,20 @@ void BlockWidget::setTips(const QString tips) + m_tipLabel->show(); + m_listView->hide(); + m_tipLabel->setText(tips); +- m_cancelButton->setText(tr("Cancel")); +- m_confirmButton->setText(tr("Confrim")); ++ QString cancelStrEText = getElidedText(font(), m_cancelButton->width() - m_cancelButton->contentsMargins().left() - m_cancelButton->contentsMargins().right(), tr("Cancel")); ++ if (cancelStrEText == tr("Cancel")) { ++ m_cancelButton->setText(tr("Cancel")); ++ } else if (cancelStrEText != tr("Cancel")) { ++ m_cancelButton->setText(cancelStrEText); ++ m_cancelButton->setToolTip(tr("Cancel")); ++ } ++ QString strEText = getElidedText(font(), m_confirmButton->width() - m_confirmButton->contentsMargins().left() - m_confirmButton->contentsMargins().right(), tr("Confrim")); ++ if (strEText == tr("Confrim")) { ++ m_confirmButton->setText(tr("Confrim")); ++ } else if (strEText != tr("Confrim")) { ++ m_confirmButton->setText(strEText); ++ m_confirmButton->setToolTip(tr("Confrim")); ++ } + } + + void BlockWidget::setMsgTips(int type) +@@ -236,8 +248,20 @@ void BlockWidget::setWarning(QStringList list, int type) + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 24px;}"); + sysFont.setPointSize((16 + m_curFontSize) * m_ptToPx); + m_cancelButton->setFont(sysFont); +- m_cancelButton->setText(tr("Cancel")); +- m_confirmButton->setText(tr("Confrim")); ++ QString cancelStrEText = getElidedText(font(), m_cancelButton->width() - m_cancelButton->contentsMargins().left() - m_cancelButton->contentsMargins().right(), tr("Cancel")); ++ if (cancelStrEText == tr("Cancel")) { ++ m_cancelButton->setText(tr("Cancel")); ++ } else if (cancelStrEText != tr("Cancel")) { ++ m_cancelButton->setText(cancelStrEText); ++ m_cancelButton->setToolTip(tr("Cancel")); ++ } ++ QString strEText = getElidedText(font(), m_confirmButton->width() - m_confirmButton->contentsMargins().left() - m_confirmButton->contentsMargins().right(), tr("Confrim")); ++ if (strEText == tr("Confrim")) { ++ m_confirmButton->setText(tr("Confrim")); ++ } else if (strEText != tr("Confrim")) { ++ m_confirmButton->setText(strEText); ++ m_confirmButton->setToolTip(tr("Confrim")); ++ } + } + + QString BlockWidget::getHibited_tr_lowcase(int type) +@@ -255,3 +279,12 @@ QString BlockWidget::getHibited_tr_lowcase(int type) + return ""; + } + ++QString BlockWidget::getElidedText(QFont font, int width, QString strInfo) ++{ ++ QFontMetrics fontMetrics(font); ++ //如果当前字体下,字符串长度大于指定宽度 ++ if (fontMetrics.width(strInfo) > width) { ++ strInfo = QFontMetrics(font).elidedText(strInfo, Qt::ElideRight, width); ++ } ++ return strInfo; ++} +diff --git a/src/widgets/blockwidget.h b/src/widgets/blockwidget.h +index 748758a..fdd139b 100644 +--- a/src/widgets/blockwidget.h ++++ b/src/widgets/blockwidget.h +@@ -48,6 +48,7 @@ public: + + private: + void initUi(); ++ QString getElidedText(QFont font, int width, QString strInfo); + + private Q_SLOTS: + void onFontSizeChanged(double fontSize); +diff --git a/src/widgets/fullbackgroundwidget.cpp b/src/widgets/fullbackgroundwidget.cpp +index a124348..b59017a 100644 +--- a/src/widgets/fullbackgroundwidget.cpp ++++ b/src/widgets/fullbackgroundwidget.cpp +@@ -50,6 +50,10 @@ + #include "configuration.h" + #include <windowmanager/windowmanager.h> + using namespace kdk; ++#ifdef WITHKYSEC ++#include <kysec/libkysec.h> ++#include <kysec/status.h> ++#endif + + FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, QWidget *parent) + : QWidget(parent), m_modelLockDialog(model) +@@ -143,7 +147,7 @@ void FullBackgroundWidget::initUI() + setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); + + // 登录模式下监听屏幕插拔 +- if (isGreeterMode() && QString(qgetenv("XDG_SESSION_TYPE")) != "wayland") { ++ if (isGreeterMode() && !m_modelLockDialog->isUseWayland()) { + XRRQueryExtension(QX11Info::display(), &m_RREventBase, &m_RRErrorBase); + XRRSelectInput(QX11Info::display(), QX11Info::appRootWindow(), RRScreenChangeNotifyMask); + QtConcurrent::run([=]() { RRScreenChangeEvent(true); }); +@@ -297,7 +301,7 @@ void FullBackgroundWidget::onSecondRunParam(const QString &str) + void FullBackgroundWidget::onShowBlankScreensaver(int nDelay, bool isHasLock) + { + qDebug() << "onShowBlankScreensaver:" << nDelay << "," << isHasLock; +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, false); + + if (isHasLock) { + screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER | SCREEN_LOCK); +@@ -348,7 +352,7 @@ void FullBackgroundWidget::onShowLock(bool isStartup) + m_isStartupMode = isStartup; + show(); + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, false); + if (m_lockWidget && !m_lockWidget->isHidden()) + m_lockWidget->show(); + } +@@ -364,7 +368,7 @@ void FullBackgroundWidget::onShowSwitchUserLock() + screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK); + show(); + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, false); + if (m_lockWidget && !m_lockWidget->isHidden()) { + m_lockWidget->show(); + m_lockWidget->onShowUserListWidget(true); +@@ -377,7 +381,7 @@ void FullBackgroundWidget::onShowSessionTools() + m_isSessionTools = true; + show(); + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, true); + if (m_lockWidget && !m_lockWidget->isHidden()) + m_lockWidget->onShowPowerListWidget(true); + } +@@ -395,7 +399,7 @@ void FullBackgroundWidget::onShowAppBlockWindow(int actionType) + if (m_lockWidget && !m_lockWidget->isHidden()) + screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK); + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, true); + m_isSessionTools = true; + if (m_lockWidget && !m_lockWidget->isHidden()) + m_lockWidget->onShowInhibitWarning(lockcheck, actionType, true); +@@ -409,7 +413,7 @@ void FullBackgroundWidget::onShowMultiUsersBlockWindows(int actionType) + show(); + if (m_lockWidget && !m_lockWidget->isHidden()) + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, true); + if (m_lockWidget && !m_lockWidget->isHidden()) + m_lockWidget->onMulUsersLogined(actionType, true); + } +@@ -418,7 +422,7 @@ void FullBackgroundWidget::onShowSessionIdle() + { + onShowScreensaver(); + delayLockScreen(); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, true); + } + + void FullBackgroundWidget::onShowLockScreensaver() +@@ -460,7 +464,7 @@ void FullBackgroundWidget::onShowScreensaver() + } + } + show(); +- Q_EMIT m_modelLockDialog->lockStateChanged(true); ++ Q_EMIT m_modelLockDialog->lockStateChanged(true, false); + } + + void FullBackgroundWidget::onClearScreensaver() +@@ -469,6 +473,8 @@ void FullBackgroundWidget::onClearScreensaver() + + for (auto widget : widgetXScreensaverList) { + widget->close(); ++ delete widget; ++ widget = nullptr; + } + widgetXScreensaverList.clear(); + +@@ -515,7 +521,7 @@ void FullBackgroundWidget::onLockScreenTimeout() + void FullBackgroundWidget::onCloseScreensaver() + { + hide(); +- Q_EMIT m_modelLockDialog->lockStateChanged(false); ++ Q_EMIT m_modelLockDialog->lockStateChanged(false, false); + stopDelayLockScreen(); + screenStatus = UNDEFINED; + m_isBlank = false; +@@ -798,7 +804,7 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void * + qDebug() << "---------------------XCB_KEY_RELEASE:" << xc->detail; + onGlobalKeyRelease(xc->detail); + } else if (responseType == m_RREventBase + RRScreenChangeNotify) { +- if (isGreeterMode() && QString(qgetenv("XDG_SESSION_TYPE")) != "wayland") { ++ if (isGreeterMode() && !m_modelLockDialog->isUseWayland()) { + RRScreenChangeEvent(false); + } + } +@@ -807,13 +813,24 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void * + + void FullBackgroundWidget::onCurUserChanged(const QString &strUserName) + { +- if (isGreeterMode()) ++ if (isGreeterMode() && !m_modelLockDialog->isUseWayland()) + DisplayService::instance(m_modelLockDialog)->setCurUserName(strUserName); + } + + void FullBackgroundWidget::onAuthSucceed(QString strUserName) + { + if (getenv("USER") == strUserName) { ++ if (UniAuthService::instance()) { ++ UniAuthService::instance()->SaveLastLoginUser(strUserName); ++// 三权分立不保存秒级登录用户信息 ++#ifdef WITHKYSEC ++ if (kysec_is_disabled() || !kysec_get_3adm_status()) { ++#endif ++ UniAuthService::instance()->SaveQuickLoginUser(strUserName); ++#ifdef WITHKYSEC ++ } ++#endif ++ } + onCloseScreensaver(); + } else { + if (m_lockWidget) { +diff --git a/src/widgets/lockwidget.cpp b/src/widgets/lockwidget.cpp +index 1adb9a1..8c3b318 100644 +--- a/src/widgets/lockwidget.cpp ++++ b/src/widgets/lockwidget.cpp +@@ -207,18 +207,6 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard) + + void LockWidget::paintEvent(QPaintEvent *event) + { +- QPainter painter(this); +- painter.drawPixmap(this->geometry(), background); +- QPainterPath path; +- painter.setOpacity(0.25); +- painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; +- painter.setClipping(true); +- painter.setPen(Qt::transparent); +- path.addRect(this->rect()); +- path.setFillRule(Qt::WindingFill); +- painter.setBrush(QColor("#000000")); +- painter.setPen(Qt::transparent); +- painter.drawPath(path); + return QWidget::paintEvent(event); + } + +@@ -385,6 +373,7 @@ void LockWidget::initUI() + + void LockWidget::initConnections() + { ++ connect(UniAuthService::instance(), &UniAuthService::userChanged, this, &LockWidget::onServiceUserChanged); + connect(m_modelLockDialog, &LockDialogModel::usersInfoChanged, this, &LockWidget::onUsersInfoChanged); + connect(m_modelLockDialog, &LockDialogModel::currentUserChanged, this, &LockWidget::onCurUserChanged); + connect(m_modelLockDialog, &LockDialogModel::currentSessionChanged, this, &LockWidget::onSessionChanged); +@@ -424,6 +413,7 @@ void LockWidget::initUserWidget() + m_userListWidget->updateWidgetSize(); + m_userListWidget->hide(); + connect(m_userListWidget, &UserListWidget::userSelected, m_modelLockDialog, [=](QString strUserName) { ++ exitSubWidget(false, false); + SwitchToUser(strUserName); + }); + connect(m_userListWidget, &UserListWidget::widgetSizeChanged, m_modelLockDialog, [=]() { +@@ -466,6 +456,11 @@ void LockWidget::initPowerWidget() + connect(m_powerListWidget, &PowerListWidget::suspendClicked, this, &LockWidget::onSuspendClicked); + connect(m_powerListWidget, &PowerListWidget::itemClicked, this, &LockWidget::onPowerItemClicked); + connect(m_powerListWidget, &PowerListWidget::switchuserClicked, this, &LockWidget::onSwitchuserClicked); ++ connect(m_powerListWidget, &PowerListWidget::powerWidgetClicked, this, [=] { ++ exitSubWidget(); ++ Q_EMIT sessionToolsExit(); ++ m_isSessionTools = false; ++ }); + // m_powerListWidget->clearFocus(); + } + +@@ -1287,6 +1282,8 @@ void LockWidget::onShowPowerListWidget(bool issessionTools) + } else { + m_powerListWidget->hide(); + authDialog->inhibitShow(false); ++ //bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新 ++ authDialog->update(); + authDialog->setFocus(); + if (m_isShowResetPasswdBtn) { + m_pResetPwdBtn->show(); +@@ -1556,12 +1553,22 @@ void LockWidget::onSessionActiveChanged(bool isActive) + if (isActive) { + if (m_timerChkActive && m_timerChkActive->isActive()) { + m_timerChkActive->stop(); ++ } ++ if (m_modelLockDialog && m_modelLockDialog->isUseWayland()) { ++ QTimer::singleShot(500, this, [&, this]() { ++ if (this->isHidden()) { ++ this->show(); ++ update(); ++ } ++ startAuth(); ++ }); ++ } else { + if (this->isHidden()) { + this->show(); + update(); + } ++ startAuth(); + } +- startAuth(); + } + } + +@@ -1595,37 +1602,76 @@ void LockWidget::onAuthDialogBottomPosChanged(int nPosY) + } + } + +-void LockWidget::SwitchToUser(QString strUserName) ++void LockWidget::onServiceUserChanged(WillLoginUserInfo willSwitchUser) ++{ ++ if (!isGreeterMode() || willSwitchUser.strUserName.isEmpty()) { ++ if (isCurUserSelf(willSwitchUser.strUserName)) { // 锁屏且是当前用户则清空不处理 ++ UniAuthService::instance()->SwitchToGreeterUser(""); ++ } ++ return; ++ } ++ static QString strLastUserName = ""; ++ static quint64 llLastChangeTick = 0; ++ ++ // 清空 willSwitchUser ++ UniAuthService::instance()->SwitchToGreeterUser(""); ++ ++ quint64 curChangeTick = QDateTime::currentDateTime().currentMSecsSinceEpoch(); ++ if (willSwitchUser.strUserName == strLastUserName && curChangeTick - llLastChangeTick <= 2000) { ++ qDebug() << "onServiceUserChanged same name and time short:" << willSwitchUser.strUserName << "," ++ << curChangeTick - llLastChangeTick; ++ return; ++ } ++ strLastUserName = willSwitchUser.strUserName; ++ llLastChangeTick = curChangeTick; ++ ++ if (willSwitchUser.strUserName.isEmpty() ++ || !UniAuthService::instance()->isUserNameValid(willSwitchUser.strUserName)) { ++ qDebug() << "WillSwitchUser is NULL or invalid:" << willSwitchUser.strUserName; ++ return; ++ } ++ qDebug() << "willSwitchUser:" << willSwitchUser; ++ SwitchToUser(willSwitchUser.strUserName, true); ++} ++ ++void LockWidget::SwitchToUser(QString strUserName, bool isSwitchInCurPage /* = false*/) + { + if (m_modelLockDialog) { +- int nSwitchRet = Q_EMIT m_modelLockDialog->switchToUser(strUserName); +- if (nSwitchRet != 0) { ++ if (isSwitchInCurPage) { + Q_EMIT m_modelLockDialog->setCurrentUser(strUserName); + } else { +- // if(authDialog) { +- // authDialog->stopAuth(); +- // } +- if (!isCurUserSelf(strUserName) && !isHidden()) { +- this->hide(); +- update(); +- if (!m_timerChkActive) { +- m_timerChkActive = new QTimer(this); +- m_timerChkActive->setInterval(10 * 1000); +- connect(m_timerChkActive, &QTimer::timeout, this, [&, this]() { +- if (this->isHidden()) { +- this->show(); ++ UniAuthService::instance()->SwitchToGreeterUser(strUserName); ++ int nSwitchRet = Q_EMIT m_modelLockDialog->switchToUser(strUserName); ++ if (nSwitchRet != 0) { ++ UniAuthService::instance()->SwitchToGreeterUser(""); ++ Q_EMIT m_modelLockDialog->setCurrentUser(strUserName); ++ } else { ++ // if(authDialog) { ++ // authDialog->stopAuth(); ++ // } ++ if (!isCurUserSelf(strUserName) && !isHidden()) { ++ this->hide(); ++ update(); ++ if (!m_timerChkActive) { ++ m_timerChkActive = new QTimer(this); ++ m_timerChkActive->setInterval(10 * 1000); ++ connect(m_timerChkActive, &QTimer::timeout, this, [&, this]() { ++ if (this->isHidden() && m_modelLockDialog->sessionActive()) { ++ this->show(); ++ } ++ m_timerChkActive->stop(); ++ }); ++ } else { ++ if (m_timerChkActive->isActive()) { ++ m_timerChkActive->stop(); + } +- m_timerChkActive->stop(); +- }); +- } else { +- if (m_timerChkActive->isActive()) { +- m_timerChkActive->stop(); + } ++ m_timerChkActive->start(); ++ stopAuth(); ++ } else { ++ UniAuthService::instance()->SwitchToGreeterUser(""); ++ Q_EMIT m_modelLockDialog->setCurrentUser(strUserName); + } +- m_timerChkActive->start(); +- stopAuth(); +- } else { +- Q_EMIT m_modelLockDialog->setCurrentUser(strUserName); + } + } + } +diff --git a/src/widgets/lockwidget.h b/src/widgets/lockwidget.h +index 8095ccf..f794bd5 100644 +--- a/src/widgets/lockwidget.h ++++ b/src/widgets/lockwidget.h +@@ -24,6 +24,7 @@ + #include "userinfo.h" + #include "mediacontrolwidget.h" + #include "securityquestionanswer.h" ++#include "uniauthservice.h" + + class QListWidgetItem; + class MyListWidget; +@@ -112,7 +113,7 @@ private: + + void updateBottomButton(); + +- void SwitchToUser(QString strUserName); ++ void SwitchToUser(QString strUserName, bool isSwitchInCurPage = false); + + void refreshTranslate(); + +@@ -190,6 +191,12 @@ private Q_SLOTS: + + void onAuthDialogBottomPosChanged(int nPosY); + ++ /** ++ * @brief onServiceUserChanged 登录服务用户切换 ++ * @param willLoginUserInfo 新用户信息 ++ */ ++ void onServiceUserChanged(WillLoginUserInfo willLoginUserInfo); ++ + void onShowResetPasswdBtn(); + + void onShowResetPwdWidget(); +diff --git a/src/widgets/loginoptionswidget.cpp b/src/widgets/loginoptionswidget.cpp +index 1ffde12..105a532 100644 +--- a/src/widgets/loginoptionswidget.cpp ++++ b/src/widgets/loginoptionswidget.cpp +@@ -43,9 +43,8 @@ + #include <QJsonArray> + #include <QJsonParseError> + +-LoginOptionsWidget::LoginOptionsWidget( +- BiometricHelper *bioHelper, int uid, UniAuthService *uniauthService, QWidget *parent) +- : QWidget(parent), m_biomericProxy(bioHelper), m_uid(uid), m_uniauthService(uniauthService) ++LoginOptionsWidget::LoginOptionsWidget(BiometricHelper *bioHelper, int uid, QWidget *parent) ++ : QWidget(parent), m_biomericProxy(bioHelper), m_uid(uid) + { + m_listPriority.clear(); + m_listPriority.push_back(BioT_Face); +@@ -894,12 +893,12 @@ QPixmap LoginOptionsWidget::drawSymbolicColoredPixmap(QPixmap &source, QString c + bool LoginOptionsWidget::getBioAuthEnable(int nType) + { + bool isEnable = false; +- if (m_uniauthService && m_uniauthService->isActivatable()) { ++ if (UniAuthService::instance()->isActivatable()) { + struct passwd *pwInfo = getpwuid(m_uid); + if (pwInfo) { +- isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, ENABLETYPE_BIO); ++ isEnable = UniAuthService::instance()->getBioAuthStatus(pwInfo->pw_name, ENABLETYPE_BIO); + if (isEnable) { +- isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, nType); ++ isEnable = UniAuthService::instance()->getBioAuthStatus(pwInfo->pw_name, nType); + } + return isEnable; + } else { +@@ -912,8 +911,8 @@ bool LoginOptionsWidget::getBioAuthEnable(int nType) + + bool LoginOptionsWidget::getQRCodeEnable() + { +- if (m_uniauthService && m_uniauthService->isActivatable()) { +- return m_uniauthService->getQRCodeEnable(); ++ if (UniAuthService::instance()->isActivatable()) { ++ return UniAuthService::instance()->getQRCodeEnable(); + } else { + return true; + } +@@ -921,9 +920,9 @@ bool LoginOptionsWidget::getQRCodeEnable() + + QString LoginOptionsWidget::getDefaultDevice(QString strUserName, int bioType) + { +- if (m_uniauthService && m_uniauthService->isActivatable()) { ++ if (UniAuthService::instance()->isActivatable()) { + QString defaultDeviceName = ""; +- QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); ++ QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType); + if (!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName); + if (pDeviceInfo) { +@@ -938,13 +937,13 @@ QString LoginOptionsWidget::getDefaultDevice(QString strUserName, int bioType) + + QString LoginOptionsWidget::getDefaultDevice(QString strUserName) + { +- if (m_uniauthService && m_uniauthService->isActivatable()) { ++ if (UniAuthService::instance()->isActivatable()) { + QString defaultDeviceName = ""; + for (auto bioType : m_listPriority) { + if (bioType == UniT_Remote) { + continue; + } +- QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType); ++ QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType); + if (!strDeviceName.isEmpty()) { + DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName); + if (pDeviceInfo) { +@@ -962,10 +961,10 @@ QString LoginOptionsWidget::getDefaultDevice(QString strUserName) + QStringList LoginOptionsWidget::getAllDefDevices() + { + QStringList listDefDevices; +- if (m_uniauthService && m_uniauthService->isActivatable()) { ++ if (UniAuthService::instance()->isActivatable()) { + struct passwd *pwdInfo = getpwuid(m_uid); + if (pwdInfo) { +- listDefDevices = m_uniauthService->getAllDefaultDevice(pwdInfo->pw_name); ++ listDefDevices = UniAuthService::instance()->getAllDefaultDevice(pwdInfo->pw_name); + } + } else { + QString defaultDeviceName; +diff --git a/src/widgets/loginoptionswidget.h b/src/widgets/loginoptionswidget.h +index 3b8f6f7..7a15874 100644 +--- a/src/widgets/loginoptionswidget.h ++++ b/src/widgets/loginoptionswidget.h +@@ -42,7 +42,7 @@ class LoginOptionsWidget : public QWidget + Q_OBJECT + public: + explicit LoginOptionsWidget( +- BiometricHelper *bioHelper, int uid, UniAuthService *uniauthService, QWidget *parent = nullptr); ++ BiometricHelper *bioHelper, int uid, QWidget *parent = nullptr); + virtual ~LoginOptionsWidget(); + + bool getCurLoginOpt(int &nLoginOptType, int &nDrvId); +@@ -164,7 +164,6 @@ private: + + // ToolTip + QStringList nameList; +- UniAuthService *m_uniauthService = nullptr; + QList<int> m_listPriority; + + bool isShowUkey = false; +diff --git a/src/widgets/mpriswidget.cpp b/src/widgets/mpriswidget.cpp +index 630a374..4bca3c5 100644 +--- a/src/widgets/mpriswidget.cpp ++++ b/src/widgets/mpriswidget.cpp +@@ -165,6 +165,7 @@ void MPRISWidget::onLostMediaPath(const QString &strPath) + m_mprisDbusClient->deleteLater(); + m_mprisDbusClient = nullptr; + } ++ + m_strMediaPlayerPath.clear(); + Q_EMIT statusChanged(false); + } +@@ -209,8 +210,23 @@ void MPRISWidget::onMetadataChanged() + { + if (!m_mprisDbusClient) + return; ++ delayMetadataUpdate(); ++} + +- if (m_nPlayState == -1) { ++void MPRISWidget::delayMetadataUpdate(int nTimeout /* = 1000*/) ++{ ++ if (!m_timerDelayUpdate) { ++ m_timerDelayUpdate = new QTimer(this); ++ m_timerDelayUpdate->setSingleShot(true); ++ connect(m_timerDelayUpdate, &QTimer::timeout, this, &MPRISWidget::onDelayMetadataUpdate); ++ } ++ m_timerDelayUpdate->setInterval(nTimeout); ++ m_timerDelayUpdate->start(); ++} ++ ++void MPRISWidget::onDelayMetadataUpdate() ++{ ++ if (m_nPlayState == -1) { // 停止播放状态 + m_labelName->setText(tr("Unknown")); + m_labelArtist->setText(tr("Unknown")); + m_labelAlbum->setPixmap(PixmapToRound(m_pixmapAlbumDefault, 12, 0, 12, 0)); +diff --git a/src/widgets/mpriswidget.h b/src/widgets/mpriswidget.h +index b2d0d6f..4f018a4 100644 +--- a/src/widgets/mpriswidget.h ++++ b/src/widgets/mpriswidget.h +@@ -11,6 +11,7 @@ + #include <QVBoxLayout> + #include <QDBusConnectionInterface> + #include <QVariantMap> ++#include <QTimer> + #include "klabel.h" + + class MPRISWidget : public QFrame +@@ -35,6 +36,8 @@ public Q_SLOTS: + void onCanControlChanged(); + void updateFont(QString strFont, double fontSizeF); + ++ void onDelayMetadataUpdate(); ++ + Q_SIGNALS: + void statusChanged(bool isValid); + +@@ -45,6 +48,8 @@ private: + void initUI(); + void initConnections(); + ++ void delayMetadataUpdate(int nTimeout = 1000); ++ + private: + QDBusConnectionInterface *m_mprisMonitor = nullptr; + MPRISDBusClient *m_mprisDbusClient = nullptr; +@@ -66,6 +71,8 @@ private: + QPushButton *m_btnPrev = nullptr; + QPushButton *m_btnPlayPause = nullptr; + QPushButton *m_btnNext = nullptr; ++ ++ QTimer *m_timerDelayUpdate = nullptr; + }; + + #endif // MPRISWIDGET_H +diff --git a/src/widgets/powerlistwidget.cpp b/src/widgets/powerlistwidget.cpp +index 029f4fd..4a5f03c 100644 +--- a/src/widgets/powerlistwidget.cpp ++++ b/src/widgets/powerlistwidget.cpp +@@ -51,6 +51,24 @@ bool PowerListWidget::eventFilter(QObject *obj, QEvent *event) + return MyListWidget::eventFilter(obj, event); + } + ++void PowerListWidget::mouseReleaseEvent(QMouseEvent *event) ++{ ++ QPoint mousePos = event->pos(); ++ QList<PowerItemWidget*> itemList = this->findChildren<PowerItemWidget*>(); ++ for (PowerItemWidget* item : itemList) ++ { ++ if (item->geometry().contains(mousePos)) ++ { ++ // 如果是点击的功能按钮,不发信号,防止点击锁屏按钮时不进入锁屏 ++ return QListWidget::mouseReleaseEvent(event);; ++ } ++ } ++ // 只有点击空白处,才需要发送信号 ++ qDebug() << "Mouse press on list widget"; ++ Q_EMIT powerWidgetClicked(); ++ return QListWidget::mouseReleaseEvent(event); ++} ++ + void PowerListWidget::setPowerType(int type) + { + m_powerType = type; +diff --git a/src/widgets/powerlistwidget.h b/src/widgets/powerlistwidget.h +index 5c272fb..51ed795 100644 +--- a/src/widgets/powerlistwidget.h ++++ b/src/widgets/powerlistwidget.h +@@ -211,6 +211,7 @@ public: + protected: + bool eventFilter(QObject *obj, QEvent *event); + void changeEvent(QEvent *event); ++ void mouseReleaseEvent(QMouseEvent *event) override; + + Q_SIGNALS: + void mulUsersLogined(int inhibitType, bool iscommand); +@@ -219,6 +220,8 @@ Q_SIGNALS: + void suspendClicked(); + void switchuserClicked(); + void sureShutDown(int inhibitType, bool iscommand); ++ void powerWidgetClicked(); /*发送电源管理鼠标点击信号,在eventfilter中点击listwidget的空白处, ++ 收不到鼠标点击事件,只有在mouseReleaseEvent中能过滤到*/ + + public Q_SLOTS: + void onUpdateListInfo(); +diff --git a/src/widgets/screensaverwidget.cpp b/src/widgets/screensaverwidget.cpp +index e9190bb..cc9b494 100644 +--- a/src/widgets/screensaverwidget.cpp ++++ b/src/widgets/screensaverwidget.cpp +@@ -32,7 +32,7 @@ ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent) + : QWidget(parent), timer(nullptr), screensaver(screensaver), closing(false) + { + qDebug() << "ScreenSaverWidget::ScreenSaverWidget"; +- setAttribute(Qt::WA_DeleteOnClose); ++ // setAttribute(Qt::WA_DeleteOnClose); + setMouseTracking(true); + setFocus(); + this->installEventFilter(this); diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch --- ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch 2025-02-13 20:26:40.000000000 +0800 @@ -0,0 +1,42 @@ +From: yangmin100 <yangmin@kylinos.cn> +Date: Fri, 3 Jan 2025 17:50:02 +0800 +Subject: sync codes from v11-2503 + +--- + src/screensaver/main.cpp | 2 -- + src/widgets/authdialog.h | 2 +- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp +index 6b04da1..3c64928 100644 +--- a/src/screensaver/main.cpp ++++ b/src/screensaver/main.cpp +@@ -31,7 +31,6 @@ + #include <sys/prctl.h> + #include <signal.h> + #include <syslog.h> +-#include <ukui-log4qt.h> + + #define WORKING_DIRECTORY "/usr/share/ukui-screensaver" + bool bControlFlg = false;//是否控制面板窗口 +@@ -44,7 +43,6 @@ int main(int argc, char *argv[]) + #endif + QApplication a(argc, argv); + +- initUkuiLog4qt("ukui-screensaver-default"); + /* + prctl(PR_SET_PDEATHSIG, SIGHUP); + //加载翻译文件 +diff --git a/src/widgets/authdialog.h b/src/widgets/authdialog.h +index 2b25f86..aba243d 100644 +--- a/src/widgets/authdialog.h ++++ b/src/widgets/authdialog.h +@@ -34,7 +34,7 @@ class QPushButton; + class IconEdit; + class LockDialogModel; + class BioButtonListWidget; +-class StatuButton; ++class StatusButton; + class QTimer; + class SecurityQuestionAnswer; + diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch --- ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch 2025-02-13 20:26:40.000000000 +0800 @@ -0,0 +1,115 @@ +From: =?utf-8?b?5p2o5pWP?= <yangmin@kylinos.cn> +Date: Wed, 12 Feb 2025 01:18:50 +0000 +Subject: !112 sync codes from v11-2503 Merge pull request !112 from + liudunfa/openkylin/huanghe + +--- + src/screensaver/CMakeLists.txt | 6 +++--- + src/screensaver/main.cpp | 2 ++ + src/screensaver/screensaver.cpp | 3 ++- + src/widgets/powerlistwidget.cpp | 5 +---- + src/widgets/powerlistwidget.h | 3 --- + 5 files changed, 8 insertions(+), 11 deletions(-) + +diff --git a/src/screensaver/CMakeLists.txt b/src/screensaver/CMakeLists.txt +index ada55ef..ab4eabf 100644 +--- a/src/screensaver/CMakeLists.txt ++++ b/src/screensaver/CMakeLists.txt +@@ -64,7 +64,7 @@ set(screensaver_SRC + ../agreementinfo.cpp + ) + add_executable(ukui-screensaver-default ${screensaver_SRC}) +-target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) ++target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) + + qt5_add_resources(screensaver_Plugin_SRC + default.qrc +@@ -112,7 +112,7 @@ set(screensaver_Plugin_SRC + ) + + add_library(screensaver-default SHARED ${screensaver_Plugin_SRC}) +-target_link_libraries(screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) ++target_link_libraries(screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) + + qt5_add_resources(Screensaver_SRC + default.qrc +@@ -160,7 +160,7 @@ set(Screensaver_SRC + ) + + add_library(Screensaver STATIC ${Screensaver_SRC}) +-target_link_libraries(Screensaver Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) ++target_link_libraries(Screensaver Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets avformat avcodec ${EXTRA_LIBS}) + + install(TARGETS + ukui-screensaver-default +diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp +index 3c64928..6b04da1 100644 +--- a/src/screensaver/main.cpp ++++ b/src/screensaver/main.cpp +@@ -31,6 +31,7 @@ + #include <sys/prctl.h> + #include <signal.h> + #include <syslog.h> ++#include <ukui-log4qt.h> + + #define WORKING_DIRECTORY "/usr/share/ukui-screensaver" + bool bControlFlg = false;//是否控制面板窗口 +@@ -43,6 +44,7 @@ int main(int argc, char *argv[]) + #endif + QApplication a(argc, argv); + ++ initUkuiLog4qt("ukui-screensaver-default"); + /* + prctl(PR_SET_PDEATHSIG, SIGHUP); + //加载翻译文件 +diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp +index ace6b38..c0fce8c 100644 +--- a/src/screensaver/screensaver.cpp ++++ b/src/screensaver/screensaver.cpp +@@ -1315,7 +1315,8 @@ QPixmap Screensaver::loadFromFile(QString strPath) + void Screensaver::getVideoFormat(QString fileName) + { + char *ch; +- QByteArray ba = fileName.toLatin1(); ++ // 用toLiatin1()解析在有中文路径时回乱码 ++ QByteArray ba = fileName.toUtf8(); + ch = ba.data(); + + int ret; +diff --git a/src/widgets/powerlistwidget.cpp b/src/widgets/powerlistwidget.cpp +index 4a5f03c..9e3cbde 100644 +--- a/src/widgets/powerlistwidget.cpp ++++ b/src/widgets/powerlistwidget.cpp +@@ -96,9 +96,6 @@ void PowerListWidget::initUI() + "QScrollBar::add-line:vertical{width:0px;height:0px}" + "QScrollBar::sub-line:vertical{width:0px;height:0px}"); + // powerBtnList[0].func = &PowerListWidget::setSystemSuspend1(); +- +- m_curFontSize = m_modelLockDialog->getCurFontSize(); +- m_ptToPx = m_modelLockDialog->getPtToPx(); + } + + void PowerListWidget::initConnections() +@@ -204,7 +201,7 @@ void PowerListWidget::onUpdateListInfo() + QIcon::fromTheme(strIconTheme, QIcon(powerBtnList[i].m_strIcon)) + .pixmap(powerBtnList[i].m_icon_width, powerBtnList[i].m_icon_width), + "white")); +- btnWdg->setFontSize((16 + m_curFontSize) * m_ptToPx); ++ btnWdg->setFontSize((16 + m_modelLockDialog->getCurFontSize()) * m_modelLockDialog->getPtToPx()); + } + } + +diff --git a/src/widgets/powerlistwidget.h b/src/widgets/powerlistwidget.h +index 51ed795..df9cf3b 100644 +--- a/src/widgets/powerlistwidget.h ++++ b/src/widgets/powerlistwidget.h +@@ -240,9 +240,6 @@ private: + bool m_canSwitchUser = true; + bool m_canLogout = true; + +- double m_curFontSize; +- double m_ptToPx = 1.0; +- + int m_powerType = SAVER; + int m_powerBtnNum = 0; + diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch --- ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch 2025-02-13 20:26:40.000000000 +0800 @@ -0,0 +1,28536 @@ +From: =?utf-8?b?5p2o5pWP?= <yangmin@kylinos.cn> +Date: Thu, 13 Feb 2025 12:29:10 +0000 +Subject: =?utf-8?q?!114_update_changelog_Merge_pull_request_!114_from_?= + =?utf-8?q?=E6=9D=A8=E6=95=8F/openkylin/huanghe?= + +--- + CMakeLists.txt | 4 +- + data/CMakeLists.txt | 5 + + data/ukui-greeter/95-ukui-greeter.conf | 1 - + data/ukui-greeter/97-ukui-greeter-wlcom.conf | 4 + + data/ukui-greeter/start-greeter-session | 3 + + data/ukui-greeter/start-quick-session | 4 + + data/ukui-greeter/ukui-greeter-wlcom.desktop | 7 + + data/ukui-screensaver.desktop | 2 +- + src/CMakeLists.txt | 8 +- + src/common/definetypes.h | 6 + + src/common/plasma-shell-manager.cpp | 7 +- + src/common/plasma-shell-manager.h | 1 + + src/dbusifs/accountshelper.cpp | 4 +- + src/dbusifs/biometrichelper.h | 2 +- + src/dbusifs/dbusservermanager.cpp | 53 + + src/dbusifs/dbusservermanager.h | 50 + + src/dbusifs/enginedevice.cpp | 2 +- + src/dbusifs/freedesktophelper.h | 2 +- + src/dbusifs/login1helper.cpp | 30 +- + src/dbusifs/login1helper.h | 3 +- + src/dbusifs/sessionhelper.cpp | 260 +- + src/dbusifs/sessionhelper.h | 19 +- + src/dbusifs/uniauthservice.cpp | 2 +- + src/dbusifs/upowerhelper.h | 1 + + src/lock-backend/bioauthenticate.cpp | 8 +- + src/lock-backend/bioauthenticate.h | 2 +- + src/lock-backend/dbusupperinterface.cpp | 180 +- + src/lock-backend/dbusupperinterface.h | 38 +- + src/lock-backend/gsettingshelper.cpp | 32 +- + src/lock-backend/gsettingshelper.h | 3 + + src/lock-backend/lightdmhelper.cpp | 14 +- + src/lock-backend/lightdmhelper.h | 9 +- + src/lock-backend/main.cpp | 93 +- + src/lock-backend/pamauthenticate.cpp | 28 +- + src/lock-backend/pamauthenticate.h | 7 +- + src/lock-backend/sessionwatcher.cpp | 8 +- + src/lock-backend/sessionwatcher.h | 7 +- + src/lock-backend/switchuserutils.cpp | 2 +- + src/lock-dialog/backenddbushelper.cpp | 13 +- + src/lock-dialog/backenddbushelper.h | 8 +- + src/lock-dialog/languagesetting.cpp | 2 +- + src/lock-dialog/lockdialogmodel.cpp | 4 +- + src/lock-dialog/lockdialogmodel.h | 8 +- + src/lock-dialog/lockdialogperformer.cpp | 24 +- + src/lock-dialog/lockdialogperformer.h | 2 + + src/lock-dialog/main.cpp | 59 +- + src/lock-dialog/pam-tally.c | 30 +- + src/ukccplugins/CMakeLists.txt | 3 + + src/ukccplugins/screenlock/CMakeLists.txt | 47 + + src/ukccplugins/screenlock/pictureunit.cpp | 124 + + src/ukccplugins/screenlock/pictureunit.h | 61 + + src/ukccplugins/screenlock/screenlock.cpp | 277 ++ + src/ukccplugins/screenlock/screenlock.h | 83 + + src/ukccplugins/screenlock/screenlockui.cpp | 713 +++ + src/ukccplugins/screenlock/screenlockui.h | 123 + + src/ukccplugins/screensaver/CMakeLists.txt | 51 + + src/ukccplugins/screensaver/previewwidget.cpp | 35 + + src/ukccplugins/screensaver/previewwidget.h | 22 + + src/ukccplugins/screensaver/screensaver.cpp | 379 ++ + src/ukccplugins/screensaver/screensaver.h | 94 + + src/ukccplugins/screensaver/screensaverpluginso.h | 27 + + src/ukccplugins/screensaver/screensaverui.cpp | 505 ++ + src/ukccplugins/screensaver/screensaverui.h | 94 + + .../sessiondbus/screenlockinterface.cpp | 153 + + src/ukccplugins/sessiondbus/screenlockinterface.h | 63 + + .../sessiondbus/screensaverinterface.cpp | 193 + + src/ukccplugins/sessiondbus/screensaverinterface.h | 78 + + src/userinfo.cpp | 4 +- + src/widgets/authdialog.cpp | 56 +- + src/widgets/fullbackgroundwidget.cpp | 34 +- + src/widgets/fullbackgroundwidget.h | 5 +- + src/widgets/iconedit.cpp | 3 + + src/widgets/lockwidget.cpp | 67 +- + src/widgets/screensaverwidget.cpp | 5 +- + tests/CMakeLists.txt | 50 + + tests/auto_test.sh | 56 + + tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp | 58 + + tests/kt-test-utils/cpp-stub-ext/stub-shadow.h | 171 + + tests/kt-test-utils/cpp-stub-ext/stubext.h | 129 + + tests/kt-test-utils/cpp-stub/addr_any.h | 280 ++ + tests/kt-test-utils/cpp-stub/addr_pri.h | 177 + + tests/kt-test-utils/cpp-stub/elfio.hpp | 4888 ++++++++++++++++++++ + tests/kt-test-utils/cpp-stub/stub.h | 360 ++ + tests/unit_test_account_helper/CMakeLists.txt | 64 + + tests/unit_test_account_helper/main.cpp | 12 + + .../unit_test_account_helper.cpp | 65 + + tests/unit_test_auth_pam/CMakeLists.txt | 86 + + tests/unit_test_auth_pam/main.cpp | 12 + + tests/unit_test_auth_pam/unit_test_auth_pam.cpp | 377 ++ + tests/unit_test_backend_dbus/CMakeLists.txt | 68 + + tests/unit_test_backend_dbus/main.cpp | 12 + + .../unit_test_backend_dbus.cpp | 423 ++ + tests/unit_test_biometric_helper/CMakeLists.txt | 66 + + tests/unit_test_biometric_helper/main.cpp | 12 + + .../unit_test_biometric_helper.cpp | 131 + + tests/unit_test_common/CMakeLists.txt | 89 + + tests/unit_test_common/main.cpp | 12 + + tests/unit_test_common/unit_test_common.cpp | 349 ++ + tests/unit_test_dbus_interface/CMakeLists.txt | 147 + + tests/unit_test_dbus_interface/main.cpp | 12 + + .../unit_test_dbus_interface.cpp | 524 +++ + tests/unit_test_display_service/CMakeLists.txt | 59 + + tests/unit_test_display_service/main.cpp | 12 + + .../unit_test_display_service.cpp | 69 + + tests/unit_test_engine_device/CMakeLists.txt | 66 + + tests/unit_test_engine_device/main.cpp | 12 + + .../unit_test_engine_device.cpp | 451 ++ + tests/unit_test_freedesktop_helper/CMakeLists.txt | 58 + + tests/unit_test_freedesktop_helper/main.cpp | 12 + + .../unit_test_freedesktop_helper.cpp | 38 + + tests/unit_test_gsettings_helper/CMakeLists.txt | 63 + + tests/unit_test_gsettings_helper/main.cpp | 12 + + .../unit_test_gsettings_helper.cpp | 437 ++ + tests/unit_test_inputswitch_event/CMakeLists.txt | 63 + + tests/unit_test_inputswitch_event/main.cpp | 12 + + .../unit_test_inputswitch_event.cpp | 137 + + tests/unit_test_kglobalaccel_helper/CMakeLists.txt | 57 + + tests/unit_test_kglobalaccel_helper/main.cpp | 12 + + .../unit_test_kglobalaccel_helper.cpp | 36 + + tests/unit_test_lock_dialog_model/CMakeLists.txt | 86 + + tests/unit_test_lock_dialog_model/main.cpp | 12 + + .../unit_test_lock_dialog_model.cpp | 68 + + tests/unit_test_login1_helper/CMakeLists.txt | 58 + + tests/unit_test_login1_helper/main.cpp | 12 + + .../unit_test_login1_helper.cpp | 95 + + tests/unit_test_personal_data/CMakeLists.txt | 60 + + tests/unit_test_personal_data/main.cpp | 12 + + tests/unit_test_personal_data/unit_test_common.cpp | 329 ++ + .../unit_test_personal_data.cpp | 140 + + tests/unit_test_screenlock/CMakeLists.txt | 150 + + tests/unit_test_screenlock/main.cpp | 8 + + .../unit_test_screenlock/unit_test_screenlock.cpp | 96 + + tests/unit_test_screensaver/CMakeLists.txt | 149 + + tests/unit_test_screensaver/main.cpp | 8 + + .../unit_test_screensaver.cpp | 141 + + tests/unit_test_session_helper/CMakeLists.txt | 74 + + tests/unit_test_session_helper/main.cpp | 12 + + .../unit_test_session_helper.cpp | 70 + + tests/unit_test_session_watcher/CMakeLists.txt | 77 + + tests/unit_test_session_watcher/main.cpp | 12 + + .../unit_test_session_watcher.cpp | 35 + + tests/unit_test_switch_user/CMakeLists.txt | 67 + + tests/unit_test_switch_user/main.cpp | 12 + + .../unit_test_switch_user.cpp | 71 + + .../unit_test_systemupgrade_helper/CMakeLists.txt | 59 + + tests/unit_test_systemupgrade_helper/main.cpp | 12 + + .../unit_test_systemupgrade_helper.cpp | 45 + + tests/unit_test_uniauth_service/CMakeLists.txt | 62 + + tests/unit_test_uniauth_service/main.cpp | 11 + + .../unit_test_uniauth_service.cpp | 159 + + tests/unit_test_usd_helper/CMakeLists.txt | 57 + + tests/unit_test_usd_helper/main.cpp | 12 + + .../unit_test_usd_helper/unit_test_usd_helper.cpp | 32 + + ukccplugins_i18n_ts/CMakeLists.txt | 12 + + ukccplugins_i18n_ts/bo.ts | 314 ++ + ukccplugins_i18n_ts/bo_CN.ts | 493 ++ + ukccplugins_i18n_ts/de.ts | 642 +++ + ukccplugins_i18n_ts/en.ts | 314 ++ + ukccplugins_i18n_ts/en_US.ts | 319 ++ + ukccplugins_i18n_ts/es.ts | 642 +++ + ukccplugins_i18n_ts/fa.ts | 314 ++ + ukccplugins_i18n_ts/fr.ts | 642 +++ + ukccplugins_i18n_ts/kk.ts | 622 +++ + ukccplugins_i18n_ts/ky.ts | 622 +++ + ukccplugins_i18n_ts/lzh.ts | 454 ++ + ukccplugins_i18n_ts/mn.ts | 638 +++ + ukccplugins_i18n_ts/tr.ts | 499 ++ + ukccplugins_i18n_ts/ug.ts | 626 +++ + ukccplugins_i18n_ts/zh_CN.ts | 623 +++ + ukccplugins_i18n_ts/zh_HK.ts | 647 +++ + ukccplugins_i18n_ts/zh_Hant.ts | 642 +++ + 171 files changed, 25543 insertions(+), 421 deletions(-) + create mode 100644 data/ukui-greeter/97-ukui-greeter-wlcom.conf + create mode 100755 data/ukui-greeter/start-greeter-session + create mode 100755 data/ukui-greeter/start-quick-session + create mode 100644 data/ukui-greeter/ukui-greeter-wlcom.desktop + create mode 100644 src/dbusifs/dbusservermanager.cpp + create mode 100644 src/dbusifs/dbusservermanager.h + create mode 100644 src/ukccplugins/CMakeLists.txt + create mode 100644 src/ukccplugins/screenlock/CMakeLists.txt + create mode 100644 src/ukccplugins/screenlock/pictureunit.cpp + create mode 100644 src/ukccplugins/screenlock/pictureunit.h + create mode 100644 src/ukccplugins/screenlock/screenlock.cpp + create mode 100644 src/ukccplugins/screenlock/screenlock.h + create mode 100644 src/ukccplugins/screenlock/screenlockui.cpp + create mode 100644 src/ukccplugins/screenlock/screenlockui.h + create mode 100644 src/ukccplugins/screensaver/CMakeLists.txt + create mode 100644 src/ukccplugins/screensaver/previewwidget.cpp + create mode 100644 src/ukccplugins/screensaver/previewwidget.h + create mode 100644 src/ukccplugins/screensaver/screensaver.cpp + create mode 100644 src/ukccplugins/screensaver/screensaver.h + create mode 100644 src/ukccplugins/screensaver/screensaverpluginso.h + create mode 100644 src/ukccplugins/screensaver/screensaverui.cpp + create mode 100644 src/ukccplugins/screensaver/screensaverui.h + create mode 100644 src/ukccplugins/sessiondbus/screenlockinterface.cpp + create mode 100644 src/ukccplugins/sessiondbus/screenlockinterface.h + create mode 100644 src/ukccplugins/sessiondbus/screensaverinterface.cpp + create mode 100644 src/ukccplugins/sessiondbus/screensaverinterface.h + create mode 100644 tests/CMakeLists.txt + create mode 100755 tests/auto_test.sh + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.h + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stubext.h + create mode 100644 tests/kt-test-utils/cpp-stub/addr_any.h + create mode 100644 tests/kt-test-utils/cpp-stub/addr_pri.h + create mode 100644 tests/kt-test-utils/cpp-stub/elfio.hpp + create mode 100644 tests/kt-test-utils/cpp-stub/stub.h + create mode 100644 tests/unit_test_account_helper/CMakeLists.txt + create mode 100644 tests/unit_test_account_helper/main.cpp + create mode 100644 tests/unit_test_account_helper/unit_test_account_helper.cpp + create mode 100644 tests/unit_test_auth_pam/CMakeLists.txt + create mode 100644 tests/unit_test_auth_pam/main.cpp + create mode 100644 tests/unit_test_auth_pam/unit_test_auth_pam.cpp + create mode 100644 tests/unit_test_backend_dbus/CMakeLists.txt + create mode 100644 tests/unit_test_backend_dbus/main.cpp + create mode 100644 tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp + create mode 100644 tests/unit_test_biometric_helper/CMakeLists.txt + create mode 100644 tests/unit_test_biometric_helper/main.cpp + create mode 100644 tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp + create mode 100644 tests/unit_test_common/CMakeLists.txt + create mode 100644 tests/unit_test_common/main.cpp + create mode 100644 tests/unit_test_common/unit_test_common.cpp + create mode 100644 tests/unit_test_dbus_interface/CMakeLists.txt + create mode 100644 tests/unit_test_dbus_interface/main.cpp + create mode 100644 tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp + create mode 100644 tests/unit_test_display_service/CMakeLists.txt + create mode 100644 tests/unit_test_display_service/main.cpp + create mode 100644 tests/unit_test_display_service/unit_test_display_service.cpp + create mode 100644 tests/unit_test_engine_device/CMakeLists.txt + create mode 100644 tests/unit_test_engine_device/main.cpp + create mode 100644 tests/unit_test_engine_device/unit_test_engine_device.cpp + create mode 100644 tests/unit_test_freedesktop_helper/CMakeLists.txt + create mode 100644 tests/unit_test_freedesktop_helper/main.cpp + create mode 100644 tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp + create mode 100644 tests/unit_test_gsettings_helper/CMakeLists.txt + create mode 100644 tests/unit_test_gsettings_helper/main.cpp + create mode 100644 tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp + create mode 100644 tests/unit_test_inputswitch_event/CMakeLists.txt + create mode 100644 tests/unit_test_inputswitch_event/main.cpp + create mode 100644 tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp + create mode 100644 tests/unit_test_kglobalaccel_helper/CMakeLists.txt + create mode 100644 tests/unit_test_kglobalaccel_helper/main.cpp + create mode 100644 tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp + create mode 100644 tests/unit_test_lock_dialog_model/CMakeLists.txt + create mode 100644 tests/unit_test_lock_dialog_model/main.cpp + create mode 100644 tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp + create mode 100644 tests/unit_test_login1_helper/CMakeLists.txt + create mode 100644 tests/unit_test_login1_helper/main.cpp + create mode 100644 tests/unit_test_login1_helper/unit_test_login1_helper.cpp + create mode 100644 tests/unit_test_personal_data/CMakeLists.txt + create mode 100644 tests/unit_test_personal_data/main.cpp + create mode 100644 tests/unit_test_personal_data/unit_test_common.cpp + create mode 100644 tests/unit_test_personal_data/unit_test_personal_data.cpp + create mode 100644 tests/unit_test_screenlock/CMakeLists.txt + create mode 100644 tests/unit_test_screenlock/main.cpp + create mode 100644 tests/unit_test_screenlock/unit_test_screenlock.cpp + create mode 100644 tests/unit_test_screensaver/CMakeLists.txt + create mode 100644 tests/unit_test_screensaver/main.cpp + create mode 100644 tests/unit_test_screensaver/unit_test_screensaver.cpp + create mode 100644 tests/unit_test_session_helper/CMakeLists.txt + create mode 100644 tests/unit_test_session_helper/main.cpp + create mode 100644 tests/unit_test_session_helper/unit_test_session_helper.cpp + create mode 100644 tests/unit_test_session_watcher/CMakeLists.txt + create mode 100644 tests/unit_test_session_watcher/main.cpp + create mode 100644 tests/unit_test_session_watcher/unit_test_session_watcher.cpp + create mode 100644 tests/unit_test_switch_user/CMakeLists.txt + create mode 100644 tests/unit_test_switch_user/main.cpp + create mode 100644 tests/unit_test_switch_user/unit_test_switch_user.cpp + create mode 100644 tests/unit_test_systemupgrade_helper/CMakeLists.txt + create mode 100644 tests/unit_test_systemupgrade_helper/main.cpp + create mode 100644 tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp + create mode 100644 tests/unit_test_uniauth_service/CMakeLists.txt + create mode 100644 tests/unit_test_uniauth_service/main.cpp + create mode 100644 tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp + create mode 100644 tests/unit_test_usd_helper/CMakeLists.txt + create mode 100644 tests/unit_test_usd_helper/main.cpp + create mode 100644 tests/unit_test_usd_helper/unit_test_usd_helper.cpp + create mode 100644 ukccplugins_i18n_ts/CMakeLists.txt + create mode 100644 ukccplugins_i18n_ts/bo.ts + create mode 100644 ukccplugins_i18n_ts/bo_CN.ts + create mode 100644 ukccplugins_i18n_ts/de.ts + create mode 100644 ukccplugins_i18n_ts/en.ts + create mode 100644 ukccplugins_i18n_ts/en_US.ts + create mode 100644 ukccplugins_i18n_ts/es.ts + create mode 100644 ukccplugins_i18n_ts/fa.ts + create mode 100644 ukccplugins_i18n_ts/fr.ts + create mode 100644 ukccplugins_i18n_ts/kk.ts + create mode 100644 ukccplugins_i18n_ts/ky.ts + create mode 100644 ukccplugins_i18n_ts/lzh.ts + create mode 100644 ukccplugins_i18n_ts/mn.ts + create mode 100644 ukccplugins_i18n_ts/tr.ts + create mode 100644 ukccplugins_i18n_ts/ug.ts + create mode 100644 ukccplugins_i18n_ts/zh_CN.ts + create mode 100644 ukccplugins_i18n_ts/zh_HK.ts + create mode 100644 ukccplugins_i18n_ts/zh_Hant.ts + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 37e601e..2e870f5 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -28,8 +28,10 @@ if(Debug) + endif() + + add_subdirectory(src) ++#add_subdirectory(tests) + add_subdirectory(i18n_ts) ++add_subdirectory(ukccplugins_i18n_ts) + add_subdirectory(data) + + # 让主目标依赖翻译文件,这样才会执行i18n +-add_dependencies(ukui-screensaver-dialog i18n) ++add_dependencies(ukui-screensaver-dialog i18n ukccplugins_i18n) +diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt +index 91e01fe..4db9e2c 100644 +--- a/data/CMakeLists.txt ++++ b/data/CMakeLists.txt +@@ -6,3 +6,8 @@ install(FILES ukui-screensaver-qt DESTINATION /etc/pam.d) + install(FILES screensaver-startup.sh DESTINATION /usr/bin) + install(FILES ukui-screensaver-dialog.desktop DESTINATION /usr/share/applications) + install(FILES org.ukui.screensaver.conf DESTINATION /etc/dbus-1/system.d) ++install(FILES ukui-greeter/ukui-greeter-wlcom.desktop DESTINATION /usr/share/xgreeters/) ++install(FILES ukui-greeter/97-ukui-greeter-wlcom.conf DESTINATION /usr/share/lightdm/lightdm.conf.d/) ++install(FILES ukui-greeter/start-greeter-session DESTINATION /usr/bin/) ++install(FILES ukui-greeter/start-quick-session DESTINATION /usr/bin/) ++ +diff --git a/data/ukui-greeter/95-ukui-greeter.conf b/data/ukui-greeter/95-ukui-greeter.conf +index 2ecb765..45a0cda 100644 +--- a/data/ukui-greeter/95-ukui-greeter.conf ++++ b/data/ukui-greeter/95-ukui-greeter.conf +@@ -2,4 +2,3 @@ + greeter-session=ukui-greeter + user-session=ukui + #greeter-setup-script=/usr/lib/ukui-greeter/ukui-greeter-nm-start.sh +-enable-autologin-user-lock=false +diff --git a/data/ukui-greeter/97-ukui-greeter-wlcom.conf b/data/ukui-greeter/97-ukui-greeter-wlcom.conf +new file mode 100644 +index 0000000..4a166bd +--- /dev/null ++++ b/data/ukui-greeter/97-ukui-greeter-wlcom.conf +@@ -0,0 +1,4 @@ ++[Seat:*] ++#greeter-session=ukui-greeter-wlcom ++#user-session=kylin-wlcom ++enable-autologin-user-lock=false +diff --git a/data/ukui-greeter/start-greeter-session b/data/ukui-greeter/start-greeter-session +new file mode 100755 +index 0000000..698158d +--- /dev/null ++++ b/data/ukui-greeter/start-greeter-session +@@ -0,0 +1,3 @@ ++#!/bin/sh ++ ++exec /usr/bin/ukui-session simpleDesk +diff --git a/data/ukui-greeter/start-quick-session b/data/ukui-greeter/start-quick-session +new file mode 100755 +index 0000000..44ee2e8 +--- /dev/null ++++ b/data/ukui-greeter/start-quick-session +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++# dbus-send --system --dest=org.ukui.UniauthBackend --type=method_call /org/ukui/UniauthBackend org.ukui.UniauthBackend.GetLastLoginUser & ++exec /usr/bin/ukui-session quickstart +diff --git a/data/ukui-greeter/ukui-greeter-wlcom.desktop b/data/ukui-greeter/ukui-greeter-wlcom.desktop +new file mode 100644 +index 0000000..239c01b +--- /dev/null ++++ b/data/ukui-greeter/ukui-greeter-wlcom.desktop +@@ -0,0 +1,7 @@ ++[Desktop Entry] ++Name=UKUI Greeter for wlcom ++Comment=UKUI Greeter for wlcom ++Exec=kylin-wlcom -s /usr/bin/start-greeter-session ++Type=Application ++X-Ubuntu-Gettext-Domain=ukui-greeter ++X-LightDM-Session-Type=wayland +diff --git a/data/ukui-screensaver.desktop b/data/ukui-screensaver.desktop +index c701dac..ebd8438 100644 +--- a/data/ukui-screensaver.desktop ++++ b/data/ukui-screensaver.desktop +@@ -8,7 +8,7 @@ Name[zh_TW]=螢幕保護程式 + Comment[tr]=Ekran koruyucuyu çalıştır ve programı kilitler + Comment[zh_CN]=运行屏幕保护及锁定程序 + Comment[zh_TW]=啟動螢幕保護程式以及鎖定程式 +-Exec=ukui-screensaver-backend ++Exec=/usr/bin/ukui-screensaver-backend %U + NoDisplay=true + X-UKUI-Autostart-Phase=Initialization + X-UKUI-Autostart-Notify=true +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index f76501d..616be9d 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -81,7 +81,6 @@ set(EXTRA_LIBS + -lrt + -lpthread + -llibnm-icon-kylin +- -lukuiinputgatherclient + ) + + #qt5_wrap_ui(dialog_SRC +@@ -154,6 +153,8 @@ qt5_add_dbus_adaptor(backend_SRC + qt5_wrap_cpp(backend_SRC + userinfo.h + agreementinfo.h ++ ukccplugins/sessiondbus/screensaverinterface.h ++ ukccplugins/sessiondbus/screenlockinterface.h + ) + + set(backend_SRC +@@ -175,13 +176,17 @@ set(backend_SRC + dbusifs/machinemodel.cpp + dbusifs/libinputswitchevent.cpp + dbusifs/systemupgradehelper.cpp ++ dbusifs/dbusservermanager.cpp + userinfo.cpp + agreementinfo.cpp + common/global_utils.cpp + common/configuration.cpp + common/biodefines.cpp + common/rsac.cpp ++ ukccplugins/sessiondbus/screensaverinterface.cpp ++ ukccplugins/sessiondbus/screenlockinterface.cpp + ) ++ + add_executable(ukui-screensaver-backend ${backend_SRC}) + target_link_libraries(ukui-screensaver-backend + Qt5::Core +@@ -220,6 +225,7 @@ target_link_libraries(screensaver-focus-helper Qt5::Core Qt5::Widgets Qt5::X11E + + add_subdirectory(VirtualKeyboard) + add_subdirectory(screensaver) ++add_subdirectory(ukccplugins) + + add_dependencies(ukui-screensaver-dialog VirtualKeyboard ukui-screensaver-default screensaver-default Screensaver) + +diff --git a/src/common/definetypes.h b/src/common/definetypes.h +index b7fbbb7..2381e65 100644 +--- a/src/common/definetypes.h ++++ b/src/common/definetypes.h +@@ -203,6 +203,11 @@ typedef enum _LOCK_CMD_ID_e + #define SS_DBUS_PATH "/" + #define SS_DBUS_INTERFACE "org.ukui.ScreenSaver" + ++#define SL_SESSION_DBUS_SERVICE "org.ukui.ScreenSaver.session.Screenlock" ++#define SL_SESSION_DBUS_PATH "/Screenlock" ++#define SS_SESSION_DBUS_SERVICE "org.ukui.ScreenSaver.session.Screensaver" ++#define SS_SESSION_DBUS_PATH "/Screensaver" ++ + enum SessionStatus + { + SESSION_AVAILABLE = 0, +@@ -352,6 +357,7 @@ enum Action + PowerReboot, + PowerUpgradeThenShutdown, + PowerShutdown, ++ TestAction, + }; + + #endif // DEFINETYPES_H +diff --git a/src/common/plasma-shell-manager.cpp b/src/common/plasma-shell-manager.cpp +index 3cd7024..6c57eab 100644 +--- a/src/common/plasma-shell-manager.cpp ++++ b/src/common/plasma-shell-manager.cpp +@@ -165,7 +165,7 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) + auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp); + auto registry = new KWayland::Client::Registry(this); + registry->create(connection->display()); +- ++#if 0 + connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [=]() { + qDebug() << "plasmaShellAnnounced..."; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); +@@ -213,7 +213,7 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) + m_shell = registry->createShell(interface.name, interface.version, this); + } + }); +- ++#endif + connect(registry, &KWayland::Client::Registry::fakeInputAnnounced, this, [=]() { + qDebug() << "fakeInputAnnounced"; + const auto interface = registry->interface(KWayland::Client::Registry::Interface::FakeInput); +@@ -237,6 +237,9 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) + [this](KWayland::Client::Keystate::Key key, KWayland::Client::Keystate::State state) { + qDebug() << "key = " << key << "state = " << state; + m_keyStateMap[key] = state; ++ if (key == KWayland::Client::Keystate::Key::CapsLock) { ++ emit capslockStateChanged(state == KWayland::Client::Keystate::Locked); ++ } + emit keyStateChanged(); + }); + m_keyState->fetchStates(); +diff --git a/src/common/plasma-shell-manager.h b/src/common/plasma-shell-manager.h +index 12b2b9d..c69beee 100644 +--- a/src/common/plasma-shell-manager.h ++++ b/src/common/plasma-shell-manager.h +@@ -49,6 +49,7 @@ public: + KWayland::Client::Keystate::State getKeyState(KWayland::Client::Keystate::Key key); + Q_SIGNALS: + void keyStateChanged(); ++ void capslockStateChanged(bool isLocked); + + private: + explicit PlasmaShellManager(QObject *parent = nullptr); +diff --git a/src/dbusifs/accountshelper.cpp b/src/dbusifs/accountshelper.cpp +index de820a3..66395ad 100644 +--- a/src/dbusifs/accountshelper.cpp ++++ b/src/dbusifs/accountshelper.cpp +@@ -16,12 +16,12 @@ + * + **/ + #include "accountshelper.h" +-#include "definetypes.h" ++#include "../common/definetypes.h" + #include <QDBusConnection> + #include <QDBusInterface> + #include <QDBusConnectionInterface> + #include <QDebug> +-#include "userinfo.h" ++#include "../../src/userinfo.h" + + AccountsHelper::AccountsHelper(QObject *parent) : QObject(parent) + { +diff --git a/src/dbusifs/biometrichelper.h b/src/dbusifs/biometrichelper.h +index dbd9fc5..9fca386 100644 +--- a/src/dbusifs/biometrichelper.h ++++ b/src/dbusifs/biometrichelper.h +@@ -21,7 +21,7 @@ + #include <QtDBus> + #include <QDBusAbstractInterface> + #include <QDBusUnixFileDescriptor> +-#include "biodefines.h" ++#include "../../src/common/biodefines.h" + + class BiometricHelper : public QDBusAbstractInterface + { +diff --git a/src/dbusifs/dbusservermanager.cpp b/src/dbusifs/dbusservermanager.cpp +new file mode 100644 +index 0000000..7135542 +--- /dev/null ++++ b/src/dbusifs/dbusservermanager.cpp +@@ -0,0 +1,53 @@ ++#include "dbusservermanager.h" ++#include "../common/definetypes.h" ++#include <QDebug> ++#include <QDBusReply> ++ ++DBusServerManager *DBusServerManager::m_instance = nullptr; ++DBusServerManager::MemCollector DBusServerManager::m_memCollector; ++DBusServerManager::DBusServerManager(QObject *parent) : QObject{ parent } ++{ ++ init(); ++} ++ ++DBusServerManager *DBusServerManager::instance(QObject *parent) ++{ ++ if (!m_instance) { ++ m_instance = new DBusServerManager(parent); ++ } ++ return m_instance; ++} ++ ++void DBusServerManager::init() ++{ ++ if (!m_dbusService) { ++ m_dbusService ++ = new QDBusInterface(FD_DBUS_SERVICE, FD_DBUS_PATH, FD_DBUS_INTERFACE, QDBusConnection::sessionBus()); ++ connect( ++ m_dbusService, ++ SIGNAL(NameOwnerChanged(QString, QString, QString)), ++ this, ++ SLOT(onDBusNameOwnerChanged(QString, QString, QString))); ++ } ++} ++ ++void DBusServerManager::onDBusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) ++{ ++ Q_UNUSED(oldOwner); ++ // qDebug() << "service status changed:" << name ++ // << (newOwner.isEmpty() ? "inactivate" : "activate"); ++ Q_EMIT dbusServerActiveChanged(name, !newOwner.isEmpty()); ++} ++ ++bool DBusServerManager::serviceExists(const QString &strService) ++{ ++ if (!m_dbusService) { ++ return false; ++ } ++ QDBusReply<bool> reply = m_dbusService->call("NameHasOwner", strService); ++ if (!reply.isValid()) { ++ qWarning() << "check service exists error:" << reply.error(); ++ return false; ++ } ++ return reply.value(); ++} +diff --git a/src/dbusifs/dbusservermanager.h b/src/dbusifs/dbusservermanager.h +new file mode 100644 +index 0000000..04b5dee +--- /dev/null ++++ b/src/dbusifs/dbusservermanager.h +@@ -0,0 +1,50 @@ ++#ifndef DBUSSERVERMANAGER_H ++#define DBUSSERVERMANAGER_H ++ ++#include <QObject> ++#include <QDBusInterface> ++ ++class DBusServerManager : public QObject ++{ ++ Q_OBJECT ++private: ++ explicit DBusServerManager(QObject *parent = nullptr); ++ ++public: ++ /** ++ * @brief 单实例 ++ * ++ * @param parent 父指针 ++ * @return DBusServerManager 单实例对象指针 ++ */ ++ static DBusServerManager *instance(QObject *parent = nullptr); ++ ++ bool serviceExists(const QString &strService); ++ ++public Q_SLOTS: ++ void onDBusNameOwnerChanged(const QString &name, ++ const QString &oldOwner, ++ const QString &newOwner); ++ ++Q_SIGNALS: ++ void dbusServerActiveChanged(const QString &strServerName, bool isActive); ++ ++private: ++ void init(); ++ ++private: ++ class MemCollector{ ++ public: ++ ~MemCollector(){ ++ if (DBusServerManager::instance()) { ++ delete DBusServerManager::instance(); ++ DBusServerManager::m_instance = nullptr; ++ } ++ } ++ }; ++ static DBusServerManager *m_instance; /** 统一认证配置服务单实例指针 */ ++ static MemCollector m_memCollector; ++ QDBusInterface *m_dbusService = nullptr; ++}; ++ ++#endif // DBUSSERVERMANAGER_H +diff --git a/src/dbusifs/enginedevice.cpp b/src/dbusifs/enginedevice.cpp +index b9ed268..81c0503 100644 +--- a/src/dbusifs/enginedevice.cpp ++++ b/src/dbusifs/enginedevice.cpp +@@ -41,7 +41,7 @@ void EngineDevice::power_device_get_devices() + int len = deviceNames.size(); + // qDebug()<<deviceNames.at(1).path(); + for (int i = 0; i < len; i++) { +- DEVICE *device = new DEVICE; ++ DEVICE *device = new DEVICE(this); + device->m_dev.path = deviceNames.at(i).path(); + getProperty(device->m_dev.path, device->m_dev); + /* connect the nofity signal to changecallback */ +diff --git a/src/dbusifs/freedesktophelper.h b/src/dbusifs/freedesktophelper.h +index 0d08ae0..2157305 100644 +--- a/src/dbusifs/freedesktophelper.h ++++ b/src/dbusifs/freedesktophelper.h +@@ -21,7 +21,7 @@ + #include <QtDBus> + #include <QDBusAbstractInterface> + #include <QDBusUnixFileDescriptor> +-#include "definetypes.h" ++#include "../common/definetypes.h" + + class FreedesktopHelper : public QDBusAbstractInterface + { +diff --git a/src/dbusifs/login1helper.cpp b/src/dbusifs/login1helper.cpp +index bbf0e1f..075779c 100644 +--- a/src/dbusifs/login1helper.cpp ++++ b/src/dbusifs/login1helper.cpp +@@ -21,6 +21,7 @@ + #include <QDBusConnection> + #include <QDBusInterface> + #include <QDBusConnectionInterface> ++#include <QDBusMessage> + + const static QString login1Service = QStringLiteral("org.freedesktop.login1"); + const static QString login1Path = QStringLiteral("/org/freedesktop/login1"); +@@ -30,12 +31,11 @@ const static QString login1SessionInterface = QStringLiteral("org.freedesktop.lo + + Login1Helper::Login1Helper(QObject *parent) : QObject(parent) + { +- QDBusInterface *loginInterface +- = new QDBusInterface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus(), this); ++ m_login1Interface = new QDBusInterface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus(), this); + // 监听manager的睡眠、唤醒信号 +- connect(loginInterface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool))); ++ connect(m_login1Interface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool))); + +- QDBusReply<QDBusObjectPath> sessionPath = loginInterface->call("GetSession", "auto"); ++ QDBusReply<QDBusObjectPath> sessionPath = m_login1Interface->call("GetSession", "auto"); + if (!sessionPath.isValid()) { + qWarning() << "Get session error:" << sessionPath.error(); + } else { +@@ -138,22 +138,26 @@ void Login1Helper::onHibitedWatcherMessage() + + void Login1Helper::setPowerManager(const QString &powerManagerfunc) + { +- QDBusInterface iface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus()); +- iface.call(powerManagerfunc, true); ++ if (m_login1Interface) { ++ m_login1Interface->call(powerManagerfunc, true); ++ } + } + + bool Login1Helper::getCanPowerManager(const QString &powerManagerfunc) + { + qDebug() << __LINE__ << __FUNCTION__ << "==========="; +- bool canFlag = true; +- QDBusInterface iface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus()); +- QDBusReply<QString> stateReplySuspend = iface.call(powerManagerfunc); +- if (stateReplySuspend.isValid() && stateReplySuspend.value() == "yes") { +- canFlag = true; ++ if (m_login1Interface) { ++ bool canFlag = true; ++ QDBusReply<QString> stateReplySuspend = m_login1Interface->call(powerManagerfunc); ++ if (stateReplySuspend.isValid() && stateReplySuspend.value() == "yes") { ++ canFlag = true; ++ } else { ++ canFlag = false; ++ } ++ return canFlag; + } else { +- canFlag = false; ++ return false; + } +- return canFlag; + } + + bool Login1Helper::isCanHibernate() +diff --git a/src/dbusifs/login1helper.h b/src/dbusifs/login1helper.h +index ea616fe..94067a6 100644 +--- a/src/dbusifs/login1helper.h ++++ b/src/dbusifs/login1helper.h +@@ -21,7 +21,7 @@ + #include <QDBusConnection> + #include <QVariantMap> + #include <QObject> +-#include "definetypes.h" ++#include "../common/definetypes.h" + + /** + * @brief login1访问工具类 +@@ -124,6 +124,7 @@ private: + bool m_isCanLogout = true; + + QString m_strSessionPath; // 当前会话路径 ++ QDBusInterface *m_login1Interface = nullptr; + }; + + #endif // LOGIN1HELPER_H +diff --git a/src/dbusifs/sessionhelper.cpp b/src/dbusifs/sessionhelper.cpp +index ccbb7d1..d3fb9dc 100644 +--- a/src/dbusifs/sessionhelper.cpp ++++ b/src/dbusifs/sessionhelper.cpp +@@ -26,7 +26,8 @@ + #include <QProcess> + + #include "login1helper.h" +-#include "lock-backend/gsettingshelper.h" ++#include "../lock-backend/gsettingshelper.h" ++#include "dbusservermanager.h" + + const static QString sessionService = QStringLiteral("org.gnome.SessionManager"); + const static QString sessionPath = QStringLiteral("/org/gnome/SessionManager"); +@@ -48,10 +49,32 @@ const QDBusArgument &InhibitInfo::operator>>(const QDBusArgument &argument, Inhi + return argument; + } + +-SessionHelper::SessionHelper(QObject *parent) : QObject(parent) ++SessionHelper::SessionHelper(QSharedPointer<Login1Helper> login1Helper, QObject *parent) : QObject(parent) ++ , m_login1Helper(login1Helper) + { +- m_sessionInterface +- = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this); ++ init(); ++} ++ ++void SessionHelper::init() ++{ ++ if (!m_sessionInterface && DBusServerManager::instance()->serviceExists(sessionService)) { ++ qDebug() << "Init session interface!"; ++ m_sessionInterface ++ = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this); ++ } else { ++ connect(DBusServerManager::instance(), &DBusServerManager::dbusServerActiveChanged, this, &SessionHelper::onSessionDbusActiveChanged); ++ } ++} ++ ++void SessionHelper::onSessionDbusActiveChanged(const QString &strServerName, bool isActive) ++{ ++ if (strServerName == sessionService && isActive) { ++ qDebug() << "Init session interface!"; ++ if (!m_sessionInterface) { ++ m_sessionInterface ++ = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this); ++ } ++ } + } + + SessionHelper::~SessionHelper() {} +@@ -59,73 +82,72 @@ SessionHelper::~SessionHelper() {} + bool SessionHelper::canAction(Action action) + { + //以下为代码结构调整 +- QString command; +- switch (action) { +- case PowerSwitchUser: +- command = QLatin1String("canSwitch"); +- break; +- case PowerHibernate: +- command = QLatin1String("canHibernate"); +- break; +- case PowerSuspend: +- command = QLatin1String("canSuspend"); +- break; +- case PowerMonitorOff: +- command = QLatin1String("canLockscreen"); +- break; +- case PowerLogout: +- command = QLatin1String("canLogout"); +- break; +- case PowerReboot: +- command = QLatin1String("canReboot"); +- break; +- case PowerShutdown: +- command = QLatin1String("canPowerOff"); +- break; +- default: +- break; +- } ++ if (m_sessionInterface) { ++ QString command; ++ switch (action) { ++ case PowerSwitchUser: ++ command = QLatin1String("canSwitch"); ++ break; ++ case PowerHibernate: ++ command = QLatin1String("canHibernate"); ++ break; ++ case PowerSuspend: ++ command = QLatin1String("canSuspend"); ++ break; ++ case PowerMonitorOff: ++ command = QLatin1String("canLockscreen"); ++ break; ++ case PowerLogout: ++ command = QLatin1String("canLogout"); ++ break; ++ case PowerReboot: ++ command = QLatin1String("canReboot"); ++ break; ++ case PowerShutdown: ++ command = QLatin1String("canPowerOff"); ++ break; ++ default: ++ break; ++ } + +- if (!m_sessionInterface->isValid()) { +- qWarning() << "dbusCall: Session QDBusInterface is invalid"; +- return false; +- } ++ if (!m_sessionInterface->isValid()) { ++ qWarning() << "dbusCall: Session QDBusInterface is invalid"; ++ return false; ++ } + +- QDBusReply<bool> testReply = m_sessionInterface->call(QLatin1String("canLockscreen")); +- if (!testReply.isValid()) { +- //解决老版本升级到新版本接口不兼容的问题,在session接口不存在的情况下,调用systemd的接口 +- QDBusError error = testReply.error(); +- Login1Helper *m_login1Helper = new Login1Helper(this); +- if (error.type() == QDBusError::UnknownMethod) { +- qInfo() << "updating ! old ukui-session dose not have canAction method"; +- if (action == PowerLogout || action == PowerMonitorOff) { +- return true; ++ QDBusReply<bool> testReply = m_sessionInterface->call(QLatin1String("canLockscreen")); ++ if (!testReply.isValid()) { ++ //解决老版本升级到新版本接口不兼容的问题,在session接口不存在的情况下,调用systemd的接口 ++ QDBusError error = testReply.error(); ++ Login1Helper *m_login1Helper = new Login1Helper(this); ++ if (error.type() == QDBusError::UnknownMethod) { ++ qInfo() << "updating ! old ukui-session dose not have canAction method"; ++ if (action == PowerLogout || action == PowerMonitorOff) { ++ return true; ++ } ++ if (m_login1Helper) { ++ return m_login1Helper->canAction(action); ++ } + } +- return m_login1Helper->canAction(action); ++ qInfo() << "dbus error"; ++ return false; ++ } ++ QDBusReply<bool> reply = m_sessionInterface->call(command); ++ qInfo() << "command = " << command << "reply = " << m_sessionInterface->call(command); ++ return reply.value(); ++ } else if (m_login1Helper){ ++ if (action == PowerLogout || action == PowerMonitorOff) { ++ return true; + } +- qInfo() << "dbus error"; ++ return m_login1Helper->canAction(action); ++ } else { + return false; + } +- +- QDBusReply<bool> reply = m_sessionInterface->call(command); +- +- qInfo() << "command = " << command << "reply = " << m_sessionInterface->call(command); +- +- return reply.value(); + } + + bool SessionHelper::doAction(const QString &powerManagerfunc) + { +- if (!m_sessionInterface->isValid()) { +- qWarning() << "dbusCall: Session QDBusInterface is invalid"; +- return false; +- } +- +- up_to_time = new QTimer(); +- up_to_time->setSingleShot(true); +- +-// qDebug() << "playShutdownMusic(powerManagerfunc) = " << playShutdownMusic(powerManagerfunc); +- ++ // qDebug() << "doAction = " << powerManagerfunc; + if (!playShutdownMusic(powerManagerfunc)) { + doPowerManager(powerManagerfunc); + } +@@ -134,61 +156,68 @@ bool SessionHelper::doAction(const QString &powerManagerfunc) + + void SessionHelper::doPowerManager(const QString &powerManagerfunc) + { +- QString command; +- if (powerManagerfunc == "Hibernate") { +- command = QLatin1String("hibernate"); +- } else if (powerManagerfunc == "Suspend") { +- command = QLatin1String("suspend"); +- } else if (powerManagerfunc == "Reboot") { +- command = QLatin1String("reboot"); +- } else if (powerManagerfunc == "PowerOff") { +- command = QLatin1String("powerOff"); +- } else if (powerManagerfunc == "Logout") { +- command = QLatin1String("logout"); +- } else if (powerManagerfunc == "SwitchUser") { +- command = QLatin1String("switchUser"); +- } else { +- return; +- } +- QDBusMessage mes = m_sessionInterface->call(command); ++ if (m_sessionInterface) { ++ QString command; ++ if (powerManagerfunc == "Hibernate") { ++ command = QLatin1String("hibernate"); ++ } else if (powerManagerfunc == "Suspend") { ++ command = QLatin1String("suspend"); ++ } else if (powerManagerfunc == "Reboot") { ++ command = QLatin1String("reboot"); ++ } else if (powerManagerfunc == "PowerOff") { ++ command = QLatin1String("powerOff"); ++ } else if (powerManagerfunc == "Logout") { ++ command = QLatin1String("logout"); ++ } else if (powerManagerfunc == "SwitchUser") { ++ command = QLatin1String("switchUser"); ++ } else { ++ return; ++ } ++ QDBusMessage mes = m_sessionInterface->call(command); + +- if (!(mes.errorName().isEmpty())) { +- Login1Helper *m_login1Helper = new Login1Helper(this); +- //本来应该判断错误类别,考虑到运行效率,不做该判断 ++ if (!(mes.errorName().isEmpty()) && m_login1Helper) { ++ //本来应该判断错误类别,考虑到运行效率,不做该判断 ++ m_login1Helper->setPowerManager(powerManagerfunc); ++ } ++ } else if (m_login1Helper) { + m_login1Helper->setPowerManager(powerManagerfunc); + } + } + + QStringList SessionHelper::getLockCheckStatus(QString type) + { +- qDBusRegisterMetaType<InhibitInfo::InhibitorInfo>(); ++ if (m_sessionInterface) { ++ qDBusRegisterMetaType<InhibitInfo::InhibitorInfo>(); + +- QVector<InhibitInfo::InhibitorInfo> resVec; ++ QVector<InhibitInfo::InhibitorInfo> resVec; + +- if (!m_sessionInterface->isValid()) { +- qDebug() << "session interface invalid!"; +- } ++ if (!m_sessionInterface->isValid()) { ++ qDebug() << "session interface invalid!"; ++ } + +- QDBusMessage result = m_sessionInterface->call("ListInhibitor", QVariant(type)); +- QList<QVariant> outArgs = result.arguments(); +- QVariant first = outArgs.at(0); +- const QDBusArgument &dbusArgs = first.value<QDBusArgument>(); ++ QDBusMessage result = m_sessionInterface->call("ListInhibitor", QVariant(type)); ++ QList<QVariant> outArgs = result.arguments(); ++ QVariant first = outArgs.at(0); ++ const QDBusArgument &dbusArgs = first.value<QDBusArgument>(); + +- dbusArgs.beginArray(); +- while (!dbusArgs.atEnd()) { +- InhibitInfo::InhibitorInfo inhibtor; +- dbusArgs >> inhibtor; +- resVec.push_back(inhibtor); +- } +- dbusArgs.endArray(); +- QStringList lockCheckList; +- for (auto iter = resVec.begin(); iter != resVec.end(); ++iter) { +- lockCheckList.append(iter->icon); +- lockCheckList.append(iter->name); +- } +- // qDebug() << "lockCheckList = " << lockCheckList; ++ dbusArgs.beginArray(); ++ while (!dbusArgs.atEnd()) { ++ InhibitInfo::InhibitorInfo inhibtor; ++ dbusArgs >> inhibtor; ++ resVec.push_back(inhibtor); ++ } ++ dbusArgs.endArray(); ++ QStringList lockCheckList; ++ for (auto iter = resVec.begin(); iter != resVec.end(); ++iter) { ++ lockCheckList.append(iter->icon); ++ lockCheckList.append(iter->name); ++ } ++ // qDebug() << "lockCheckList = " << lockCheckList; + +- return lockCheckList; ++ return lockCheckList; ++ } else { ++ return QStringList(); ++ } + } + + bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc) +@@ -203,12 +232,14 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc) + play_music = gsettingsHelper->GetSessionConf(KEY_SESSION_POWEROFF_MUSIC).toBool(); + } else if (powerManagerfunc == "Logout") { + play_music = gsettingsHelper->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC).toBool(); +- msg = m_sessionInterface->call("emitStartLogout"); +- if (!msg.errorName().isEmpty()) { +- qWarning() << "Dbus error: " << msg; ++ if (m_sessionInterface) { ++ msg = m_sessionInterface->call("emitStartLogout"); ++ if (!msg.errorName().isEmpty()) { ++ qWarning() << "Dbus error: " << msg; ++ } + } + } else { +- if (powerManagerfunc == "SwitchUser") { ++ if (powerManagerfunc == "SwitchUser" && m_sessionInterface) { + msg = m_sessionInterface->call("emitPrepareForSwitchuser"); + if (!msg.errorName().isEmpty()) { + qWarning() << "Dbus error: " << msg; +@@ -218,8 +249,13 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc) + } + + if (play_music) { +- QObject::connect(up_to_time, &QTimer::timeout, [=]() { +- doPowerManager(powerManagerfunc); ++ if (!m_timerPlayMusic) { ++ m_timerPlayMusic = new QTimer(); ++ m_timerPlayMusic->setSingleShot(true); ++ } ++ disconnect(m_timerPlayMusic, nullptr, this, nullptr); ++ connect(m_timerPlayMusic, &QTimer::timeout, this, [&, this, powerManagerfunc]() { ++ this->doPowerManager(powerManagerfunc); + return true; + }); + QString xdg_session_type = qgetenv("XDG_SESSION_TYPE"); +@@ -229,14 +265,14 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc) + } else { + QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/shutdown.wav"); + } +- up_to_time->start(5000); ++ m_timerPlayMusic->start(5000); + } else if (powerManagerfunc == "Logout") { + if (xdg_session_type == "wayland") { + QProcess::startDetached("paplay /usr/share/ukui/ukui-session-manager/logout.wav"); + } else { + QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/logout.wav"); + } +- up_to_time->start(2000); ++ m_timerPlayMusic->start(2000); + } else { + qDebug() << "error num"; + return false; +diff --git a/src/dbusifs/sessionhelper.h b/src/dbusifs/sessionhelper.h +index 6c2248c..a113b7f 100644 +--- a/src/dbusifs/sessionhelper.h ++++ b/src/dbusifs/sessionhelper.h +@@ -22,7 +22,8 @@ + #include <QFile> + #include <QTimer> + #include <QDBusArgument> +-#include "definetypes.h" ++#include <QSharedPointer> ++#include "../common/definetypes.h" + + namespace InhibitInfo + { +@@ -46,7 +47,7 @@ class SessionHelper : public QObject + { + Q_OBJECT + public: +- explicit SessionHelper(QObject *parent = nullptr); ++ explicit SessionHelper(QSharedPointer<Login1Helper> login1Helper, QObject *parent = nullptr); + + virtual ~SessionHelper(); + +@@ -56,14 +57,22 @@ public: + + bool doAction(const QString &powerManagerfunc); + +-private: +- QDBusInterface *m_sessionInterface = nullptr; ++private Q_SLOTS: ++ void onSessionDbusActiveChanged(const QString &strServerName, bool isActive); + +- QTimer *up_to_time = nullptr; ++private: ++ void init(); + + void doPowerManager(const QString &powerManagerfunc); + + bool playShutdownMusic(const QString &powerManagerfunc); ++ ++private: ++ QDBusInterface *m_sessionInterface = nullptr; ++ ++ QTimer *m_timerPlayMusic = nullptr; ++ ++ QSharedPointer<Login1Helper> m_login1Helper = nullptr; + }; + + #endif // SESSIONHELPER_H +diff --git a/src/dbusifs/uniauthservice.cpp b/src/dbusifs/uniauthservice.cpp +index 1657b24..5403907 100644 +--- a/src/dbusifs/uniauthservice.cpp ++++ b/src/dbusifs/uniauthservice.cpp +@@ -18,7 +18,7 @@ + #include "uniauthservice.h" + #include <QDebug> + #include <pwd.h> +-#include "definetypes.h" ++#include "../common/definetypes.h" + #include "freedesktophelper.h" + + /* For the type WillLoginUserInfo */ +diff --git a/src/dbusifs/upowerhelper.h b/src/dbusifs/upowerhelper.h +index 7f31af6..3db9edb 100644 +--- a/src/dbusifs/upowerhelper.h ++++ b/src/dbusifs/upowerhelper.h +@@ -19,6 +19,7 @@ + #define UPOWERHELPER_H + + #include <QDBusConnection> ++#include <QDBusMessage> + #include <QVariantMap> + #include <QObject> + +diff --git a/src/lock-backend/bioauthenticate.cpp b/src/lock-backend/bioauthenticate.cpp +index 93f1804..4cdbb4e 100644 +--- a/src/lock-backend/bioauthenticate.cpp ++++ b/src/lock-backend/bioauthenticate.cpp +@@ -16,12 +16,12 @@ + * + **/ + #include "bioauthenticate.h" +-#include "freedesktophelper.h" +-#include "biometrichelper.h" +-#include "uniauthservice.h" ++#include "../../src/dbusifs/freedesktophelper.h" ++#include "../../src/dbusifs/biometrichelper.h" ++#include "../../src/dbusifs/uniauthservice.h" + #include <pwd.h> + #include <unistd.h> +-#include "giodbus.h" ++#include "../../src/dbusifs/giodbus.h" + + BioAuthenticate::BioAuthenticate(QObject *parent) + : QObject(parent), m_systemFdHelper(new FreedesktopHelper(false, this)), m_bioTimer(nullptr) +diff --git a/src/lock-backend/bioauthenticate.h b/src/lock-backend/bioauthenticate.h +index c26e533..d295812 100644 +--- a/src/lock-backend/bioauthenticate.h ++++ b/src/lock-backend/bioauthenticate.h +@@ -21,7 +21,7 @@ + #include <QObject> + #include <QList> + #include <QMap> +-#include "biodefines.h" ++#include "../../src/common/biodefines.h" + + class BiometricHelper; + class FreedesktopHelper; +diff --git a/src/lock-backend/dbusupperinterface.cpp b/src/lock-backend/dbusupperinterface.cpp +index db209a7..d4eadcc 100644 +--- a/src/lock-backend/dbusupperinterface.cpp ++++ b/src/lock-backend/dbusupperinterface.cpp +@@ -17,11 +17,11 @@ + **/ + #include "dbusupperinterface.h" + #include "lightdmhelper.h" +-#include "login1helper.h" +-#include "definetypes.h" +-#include "configuration.h" +-#include "gsettingshelper.h" +-#include "usdhelper.h" ++#include "../../src/dbusifs/login1helper.h" ++#include "../../src/common/definetypes.h" ++#include "../../src/common/configuration.h" ++#include "../../src/lock-backend/gsettingshelper.h" ++#include "../../src/dbusifs/usdhelper.h" + #include <QJsonValue> + #include <QJsonObject> + #include <QJsonDocument> +@@ -29,25 +29,34 @@ + #include <QJsonArray> + #include <QJsonParseError> + #include <QDebug> +-#include "qtlocalpeer.h" +-#include "switchuserutils.h" +-#include "pamauthenticate.h" +-#include "upowerhelper.h" +-#include "accountshelper.h" +-#include "sessionhelper.h" +-#include "systemupgradehelper.h" +-#include "sessionwatcher.h" +-#include "freedesktophelper.h" +-#include "bioauthenticate.h" +-#include "rsac.h" +-#include "kglobalaccelhelper.h" +-#include "personalizeddata.h" +-#include "libinputswitchevent.h" +-#include "uniauthservice.h" ++#include "../../src/QtSingleApplication/qtlocalpeer.h" ++#include "../../src/lock-backend/switchuserutils.h" ++#include "../../src/lock-backend/pamauthenticate.h" ++#include "../../src/dbusifs/upowerhelper.h" ++#include "../../src/dbusifs/accountshelper.h" ++#include "../../src/dbusifs/sessionhelper.h" ++#include "../../src/dbusifs/systemupgradehelper.h" ++#include "../../src/lock-backend/sessionwatcher.h" ++#include "../../src/dbusifs/freedesktophelper.h" ++#include "../../src/lock-backend/bioauthenticate.h" ++#include "../../src/common/rsac.h" ++#include "../../src/dbusifs/kglobalaccelhelper.h" ++#include "../../src/lock-backend/personalizeddata.h" ++#include "../../src/dbusifs/libinputswitchevent.h" ++#include "../../src/dbusifs/uniauthservice.h" ++#include <syslog.h> + + #define CONFIG_FILE "/usr/share/ukui-greeter/ukui-greeter.conf" + + DbusUpperInterface::DbusUpperInterface(QObject *parent) : QObject(parent) ++{ ++ m_bLockState = false; ++ m_bSlpState = false; ++} ++ ++DbusUpperInterface::~DbusUpperInterface() {} ++ ++void DbusUpperInterface::init() + { + initData(); + initConnections(); +@@ -56,130 +65,152 @@ DbusUpperInterface::DbusUpperInterface(QObject *parent) : QObject(parent) + + void DbusUpperInterface::initData() + { +- m_bLockState = false; +- m_bSlpState = false; ++ syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initData begin!!"); + m_config = Configuration::instance(this); +- m_accountsHelper = new AccountsHelper(this); +- m_lightDmHelper = new LightDMHelper(m_accountsHelper, m_config, this); +- m_login1Helper = new Login1Helper(this); +- m_gsettingsHelper = new GSettingsHelper(this); +- m_bioAuth = new BioAuthenticate(this); +- m_pamAuth = new PamAuthenticate(m_lightDmHelper, this); +- m_usdHelper = new UsdHelper(this); +- m_upowerHelper = new UpowerHelper(this); +- m_sessionHelper = new SessionHelper(this); +- m_systemsUpgradeHelper = new SystemUpgradeHelper(this); +- m_sessionWatcher = new SessionWatcher(m_gsettingsHelper, this); +- m_kglobalHelper = new KglobalAccelHelper(this); +- m_libinputSwitchEvent = new LibinputSwitchEvent(this); ++ m_accountsHelper = QSharedPointer<AccountsHelper>(new AccountsHelper(this)); ++ m_lightDmHelper = QSharedPointer<LightDMHelper>(new LightDMHelper(m_accountsHelper, m_config, this)); ++ m_login1Helper = QSharedPointer<Login1Helper>(new Login1Helper(this)); ++ m_gsettingsHelper = QSharedPointer<GSettingsHelper>(new GSettingsHelper(this)); ++ m_bioAuth = QSharedPointer<BioAuthenticate>(new BioAuthenticate(this)); ++ m_pamAuth = QSharedPointer<PamAuthenticate>(new PamAuthenticate(m_lightDmHelper, this)); ++ m_usdHelper = QSharedPointer<UsdHelper>(new UsdHelper(this)); ++ m_upowerHelper = QSharedPointer<UpowerHelper>(new UpowerHelper(this)); ++ m_sessionHelper = QSharedPointer<SessionHelper>(new SessionHelper(m_login1Helper, this)); ++ m_systemsUpgradeHelper = QSharedPointer<SystemUpgradeHelper>(new SystemUpgradeHelper(this)); ++ m_sessionWatcher = QSharedPointer<SessionWatcher>(new SessionWatcher(m_gsettingsHelper, this)); ++ m_kglobalHelper = QSharedPointer<KglobalAccelHelper>(new KglobalAccelHelper(this)); ++ m_libinputSwitchEvent = QSharedPointer<LibinputSwitchEvent>(new LibinputSwitchEvent(this)); + + m_config->initShareConfig(); + m_config->setShareConfigValue("timeType", m_gsettingsHelper->GetUkccPluginsConf(KEY_HOUR_SYSTEM).toInt()); + m_config->setShareConfigValue("dateType", m_gsettingsHelper->GetUkccPluginsConf(KEY_DATE).toString()); + m_config->setShareConfigValue("fontSize", m_gsettingsHelper->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE).toDouble()); + m_config->setShareConfigValue("themeColor", m_gsettingsHelper->GetThemeStyleConf(KEY_THEME_COLOR).toString()); ++ syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initData end!!"); + } + + void DbusUpperInterface::initConnections() + { + if (m_lightDmHelper) { +- connect(m_lightDmHelper, &LightDMHelper::usersInfoChanged, this, &DbusUpperInterface::onUsersInfoChanged); ++ connect(m_lightDmHelper.get(), &LightDMHelper::usersInfoChanged, this, &DbusUpperInterface::onUsersInfoChanged); + connect( +- m_lightDmHelper, &LightDMHelper::currentSessionChanged, this, &DbusUpperInterface::onCurrentSessionChanged); ++ m_lightDmHelper.get(), ++ &LightDMHelper::currentSessionChanged, ++ this, ++ &DbusUpperInterface::onCurrentSessionChanged); + } + if (m_login1Helper) { +- connect(m_login1Helper, &Login1Helper::requestLock, this, &DbusUpperInterface::onLogin1ReqLock); +- connect(m_login1Helper, &Login1Helper::requestUnlock, this, &DbusUpperInterface::onLogin1ReqUnLock); +- connect(m_login1Helper, &Login1Helper::PrepareForSleep, this, &DbusUpperInterface::onLogin1PrepareForSleep); ++ connect(m_login1Helper.get(), &Login1Helper::requestLock, this, &DbusUpperInterface::onLogin1ReqLock); ++ connect(m_login1Helper.get(), &Login1Helper::requestUnlock, this, &DbusUpperInterface::onLogin1ReqUnLock); + connect( +- m_login1Helper, ++ m_login1Helper.get(), &Login1Helper::PrepareForSleep, this, &DbusUpperInterface::onLogin1PrepareForSleep); ++ connect( ++ m_login1Helper.get(), + &Login1Helper::sessionActiveChanged, + this, + &DbusUpperInterface::onLogin1SessionActiveChanged); + connect( +- m_login1Helper, &Login1Helper::blockInhibitedChanged, this, &DbusUpperInterface::onBlockInhibitedChanged); ++ m_login1Helper.get(), ++ &Login1Helper::blockInhibitedChanged, ++ this, ++ &DbusUpperInterface::onBlockInhibitedChanged); + } + if (m_gsettingsHelper) { + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::lockScreenConfigChanged, + this, + &DbusUpperInterface::onLockScreenConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::screenSaverConfigChanged, + this, + &DbusUpperInterface::onScreenSaverConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::powerManagerConfigChanged, + this, + &DbusUpperInterface::onPowerManagerConfigChanged); + connect( +- m_gsettingsHelper, &GSettingsHelper::mateBgConfigChanged, this, &DbusUpperInterface::onMateBgConfigChanged); ++ m_gsettingsHelper.get(), ++ &GSettingsHelper::mateBgConfigChanged, ++ this, ++ &DbusUpperInterface::onMateBgConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::ukccPluginsConfigChanged, + this, + &DbusUpperInterface::onUkccPluginsConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::themeStyleConfigChanged, + this, + &DbusUpperInterface::onThemeStyleConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::sessionConfigChanged, + this, + &DbusUpperInterface::onSessionConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::keyboardConfigChanged, + this, + &DbusUpperInterface::onKeyboardConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::usdMediaKeysConfigChanged, + this, + &DbusUpperInterface::onUsdMediaKeysConfigChanged); + connect( +- m_gsettingsHelper, ++ m_gsettingsHelper.get(), + &GSettingsHelper::usdMediaStateKeysConfigChanged, + this, + &DbusUpperInterface::onUsdMediaStateKeysConfigChanged); + } + if (m_bioAuth) { +- connect(m_bioAuth, &BioAuthenticate::bioAuthShowMessage, this, &DbusUpperInterface::onBioAuthShowMessage); ++ connect(m_bioAuth.get(), &BioAuthenticate::bioAuthShowMessage, this, &DbusUpperInterface::onBioAuthShowMessage); ++ connect( ++ m_bioAuth.get(), ++ &BioAuthenticate::bioServiceStatusChanged, ++ this, ++ &DbusUpperInterface::onBioServiceStatusChanged); ++ connect(m_bioAuth.get(), &BioAuthenticate::bioDeviceChanged, this, &DbusUpperInterface::onBioDeviceChanged); + connect( +- m_bioAuth, &BioAuthenticate::bioServiceStatusChanged, this, &DbusUpperInterface::onBioServiceStatusChanged); +- connect(m_bioAuth, &BioAuthenticate::bioDeviceChanged, this, &DbusUpperInterface::onBioDeviceChanged); +- connect(m_bioAuth, &BioAuthenticate::bioAuthStateChanged, this, &DbusUpperInterface::onBioAuthStateChanged); +- connect(m_bioAuth, &BioAuthenticate::bioAuthFrameData, this, &DbusUpperInterface::onBioAuthFrameData); +- connect(m_bioAuth, &BioAuthenticate::bioAuthCompleted, this, &DbusUpperInterface::onBioAuthCompleted); ++ m_bioAuth.get(), &BioAuthenticate::bioAuthStateChanged, this, &DbusUpperInterface::onBioAuthStateChanged); ++ connect(m_bioAuth.get(), &BioAuthenticate::bioAuthFrameData, this, &DbusUpperInterface::onBioAuthFrameData); ++ connect(m_bioAuth.get(), &BioAuthenticate::bioAuthCompleted, this, &DbusUpperInterface::onBioAuthCompleted); + if (m_pamAuth) { + connect( +- m_pamAuth, &PamAuthenticate::authenticationComplete, m_bioAuth, &BioAuthenticate::onPamAuthComplete); ++ m_pamAuth.get(), ++ &PamAuthenticate::authenticationComplete, ++ m_bioAuth.get(), ++ &BioAuthenticate::onPamAuthComplete); + } + } + if (m_pamAuth) { +- connect(m_pamAuth, &PamAuthenticate::showMessage, this, &DbusUpperInterface::onPamShowMessage); +- connect(m_pamAuth, &PamAuthenticate::showPrompt, this, &DbusUpperInterface::onPamShowPrompt); +- connect(m_pamAuth, &PamAuthenticate::authenticationComplete, this, &DbusUpperInterface::onPamAuthCompleted); ++ connect(m_pamAuth.get(), &PamAuthenticate::showMessage, this, &DbusUpperInterface::onPamShowMessage); ++ connect(m_pamAuth.get(), &PamAuthenticate::showPrompt, this, &DbusUpperInterface::onPamShowPrompt); ++ connect( ++ m_pamAuth.get(), &PamAuthenticate::authenticationComplete, this, &DbusUpperInterface::onPamAuthCompleted); + } + if (m_upowerHelper) { +- connect(m_upowerHelper, &UpowerHelper::batteryStatusChanged, this, &DbusUpperInterface::onBatteryStatusChanged); +- connect(m_upowerHelper, &UpowerHelper::batteryChanged, this, &DbusUpperInterface::onBatteryChanged); +- connect(m_upowerHelper, &UpowerHelper::lidStateChanged, this, &DbusUpperInterface::onLidStateChanged); ++ connect( ++ m_upowerHelper.get(), ++ &UpowerHelper::batteryStatusChanged, ++ this, ++ &DbusUpperInterface::onBatteryStatusChanged); ++ connect(m_upowerHelper.get(), &UpowerHelper::batteryChanged, this, &DbusUpperInterface::onBatteryChanged); ++ connect(m_upowerHelper.get(), &UpowerHelper::lidStateChanged, this, &DbusUpperInterface::onLidStateChanged); + } + if (m_sessionWatcher) { +- connect(m_sessionWatcher, &SessionWatcher::sessionIdle, this, &DbusUpperInterface::onSessionIdleReceived); +- connect(m_sessionWatcher, &SessionWatcher::sessionIdle, this, [=]() { ++ connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdle, this, &DbusUpperInterface::onSessionIdleReceived); ++ connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdle, this, [=]() { + QDBusMessage message; + message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "SecondRunParam"); + message << "SessionIdle"; + QDBusConnection::sessionBus().send(message); + }); +- connect(m_sessionWatcher, &SessionWatcher::sessionIdleExit, this, &DbusUpperInterface::onSessionIdleExit); ++ connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdleExit, this, &DbusUpperInterface::onSessionIdleExit); + } + connect( + &m_procLockDialog, +@@ -188,7 +219,7 @@ void DbusUpperInterface::initConnections() + SLOT(onLockDialogProcExit(int, QProcess::ExitStatus))); + if (m_libinputSwitchEvent) { + connect( +- m_libinputSwitchEvent, ++ m_libinputSwitchEvent.get(), + &LibinputSwitchEvent::tabletModeStatusChanged, + this, + &DbusUpperInterface::onTabletModeChanged); +@@ -628,8 +659,7 @@ bool DbusUpperInterface::checkScreenDialogRunning() + void DbusUpperInterface::emitLockState(bool val, bool isSessionTools) + { + qDebug() << "emitLockState state = " << val; +- +- if (val != m_bBlockShortcutState) { ++ if (val != m_bBlockShortcutState && m_kglobalHelper) { + m_kglobalHelper->blockShortcut(val); + m_bBlockShortcutState = val; + qDebug() << " block all shortcut " +@@ -991,7 +1021,7 @@ QJsonArray DbusUpperInterface::GenerateUserInfoList() + objUserInfo["lang"] = userInfo->lang(); + objUserInfo["headImg"] = userInfo->headImage(); + objUserInfo["systemAccount"] = userInfo->isSystemAccount(); +- KylinUserDatePtr ptr = KYLINUSERDATAMNG::getInstance()->GetUserPtr(userInfo->name()); ++ KylinUserDatePtr ptr = KYLINUSERDATAMNG::instance()->GetUserPtr(userInfo->name()); + if (nullptr != ptr) { + if (!ptr->backgroundPath().isEmpty()) { + objUserInfo["greeterBackGround"] = ptr->backgroundPath(); +@@ -1660,6 +1690,7 @@ void DbusUpperInterface::onKeyboardConfigChanged(QString strKey, QVariant value) + { + QJsonObject retObj; + retObj["CmdId"] = LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED; ++ retObj["Key"] = strKey; + switch (value.type()) { + case QVariant::Bool: + retObj["Value"] = value.toBool(); +@@ -2666,3 +2697,8 @@ int DbusUpperInterface::SetPowerManager(const QJsonObject &objInfo) + + return nRet; + } ++ ++QSharedPointer<GSettingsHelper> DbusUpperInterface::getGSettingsInstance() ++{ ++ return m_gsettingsHelper; ++} +diff --git a/src/lock-backend/dbusupperinterface.h b/src/lock-backend/dbusupperinterface.h +index 2797db9..e9898bb 100644 +--- a/src/lock-backend/dbusupperinterface.h ++++ b/src/lock-backend/dbusupperinterface.h +@@ -25,9 +25,11 @@ + #include <QDBusInterface> + #include <QDBusUnixFileDescriptor> + #include <QProcess> ++#include <QSharedPointer> + #include <QTimer> +-#include "utils.h" +-#include "rsac.h" ++#include "../../src/common/utils.h" ++#include "../../src/common/rsac.h" ++#include "../../src/common/definetypes.h" + + class LightDMHelper; + class Login1Helper; +@@ -66,6 +68,10 @@ public: + */ + explicit DbusUpperInterface(QObject *parent = nullptr); + ++ virtual ~DbusUpperInterface(); ++ ++ void init(); ++ + public: + bool checkScreenDialogRunning(); + void emitLockState(bool val, bool isSessionTools = false); +@@ -151,6 +157,8 @@ public: + + bool sendPassword(const QString username, QByteArray password); + ++ QSharedPointer<GSettingsHelper> getGSettingsInstance(); ++ + public Q_SLOTS: + /** + * @brief 服务退出 +@@ -402,10 +410,10 @@ private: + bool SendUpdateInfoSig(QString strJson); + + private: +- LightDMHelper *m_lightDmHelper = nullptr; /**< lightdm工具实例 */ +- Login1Helper *m_login1Helper = nullptr; /**< login1工具实例 */ ++ QSharedPointer<LightDMHelper> m_lightDmHelper = nullptr; /**< lightdm工具实例 */ ++ QSharedPointer<Login1Helper> m_login1Helper = nullptr; /**< login1工具实例 */ + Configuration *m_config = nullptr; +- GSettingsHelper *m_gsettingsHelper = nullptr; ++ QSharedPointer<GSettingsHelper> m_gsettingsHelper = nullptr; + QProcess m_procLockDialog; + bool m_bLockState; + bool m_bBlankState = false; +@@ -415,19 +423,19 @@ private: + int m_timerCount = 0; + QTimer *m_timerLock = nullptr; + QDBusUnixFileDescriptor m_inhibitFileDescriptor; +- PamAuthenticate *m_pamAuth = nullptr; +- UsdHelper *m_usdHelper = nullptr; +- UpowerHelper *m_upowerHelper = nullptr; +- AccountsHelper *m_accountsHelper = nullptr; ++ QSharedPointer<PamAuthenticate> m_pamAuth = nullptr; ++ QSharedPointer<UsdHelper> m_usdHelper = nullptr; ++ QSharedPointer<UpowerHelper> m_upowerHelper = nullptr; ++ QSharedPointer<AccountsHelper> m_accountsHelper = nullptr; + bool lockState = false; +- SessionHelper *m_sessionHelper = nullptr; +- SystemUpgradeHelper *m_systemsUpgradeHelper = nullptr; +- SessionWatcher *m_sessionWatcher = nullptr; +- BioAuthenticate *m_bioAuth = nullptr; ++ QSharedPointer<SessionHelper> m_sessionHelper = nullptr; ++ QSharedPointer<SystemUpgradeHelper> m_systemsUpgradeHelper = nullptr; ++ QSharedPointer<SessionWatcher> m_sessionWatcher = nullptr; ++ QSharedPointer<BioAuthenticate> m_bioAuth = nullptr; + RSAC rsac; + QByteArray pubKey, priKey; +- KglobalAccelHelper *m_kglobalHelper = nullptr; +- LibinputSwitchEvent *m_libinputSwitchEvent = nullptr; ++ QSharedPointer<KglobalAccelHelper> m_kglobalHelper = nullptr; ++ QSharedPointer<LibinputSwitchEvent> m_libinputSwitchEvent = nullptr; + bool m_bBlockShortcutState = false; + }; + +diff --git a/src/lock-backend/gsettingshelper.cpp b/src/lock-backend/gsettingshelper.cpp +index fd29271..5e08b4b 100644 +--- a/src/lock-backend/gsettingshelper.cpp ++++ b/src/lock-backend/gsettingshelper.cpp +@@ -18,7 +18,7 @@ + #include "gsettingshelper.h" + #include <QVariant> + #include <QDebug> +-#include "definetypes.h" ++#include "../common/definetypes.h" + + GSettingsHelper::GSettingsHelper(QObject *parent) : QObject(parent) {} + +@@ -294,10 +294,10 @@ bool GSettingsHelper::initUsdMediaKeys() + bool GSettingsHelper::initUsdMediaStateKeys() + { + if (!m_gsUsdMediaStateKeys) { +- if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA)) { ++ if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA)) { + m_gsUsdMediaStateKeys = new QGSettings(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA, "", this); +- connect(m_gsUsdMediaStateKeys, &QGSettings::changed, +- this, &GSettingsHelper::onUsdMediaStateKeysConfigChanged); ++ connect( ++ m_gsUsdMediaStateKeys, &QGSettings::changed, this, &GSettingsHelper::onUsdMediaStateKeysConfigChanged); + QStringList keys = m_gsUsdMediaStateKeys->keys(); + if (keys.contains(KEY_RFKILL_STATE)) { + m_rfkillState = m_gsUsdMediaStateKeys->get(KEY_RFKILL_STATE).toInt(); +@@ -536,6 +536,18 @@ bool GSettingsHelper::SetScreenSaverConf(QString strKey, QVariant value) + return false; + } + ++QVariant GSettingsHelper::ResetScreenSaverConf(QString strKey) ++{ ++ QVariant defValue; ++ if (initLockScreen()) { ++ if (m_gsLockScreen->keys().contains(strKey)) { ++ m_gsLockScreen->reset(strKey); ++ defValue = m_gsLockScreen->get(strKey); ++ } ++ } ++ return defValue; ++} ++ + QVariant GSettingsHelper::GetLockScreenConf(QString strKey) + { + QVariant varValue; +@@ -582,6 +594,18 @@ bool GSettingsHelper::SetLockScreenConf(QString strKey, QVariant value) + return false; + } + ++QVariant GSettingsHelper::ResetLockScreenConf(QString strKey) ++{ ++ QVariant defValue; ++ if (initLockScreen()) { ++ if (m_gsLockScreen->keys().contains(strKey)) { ++ m_gsLockScreen->reset(strKey); ++ defValue = m_gsLockScreen->get(strKey); ++ } ++ } ++ return defValue; ++} ++ + QVariant GSettingsHelper::GetPowerManagerConf(QString strKey) + { + QVariant varValue; +diff --git a/src/lock-backend/gsettingshelper.h b/src/lock-backend/gsettingshelper.h +index 70303a9..4aa4fdf 100644 +--- a/src/lock-backend/gsettingshelper.h ++++ b/src/lock-backend/gsettingshelper.h +@@ -20,6 +20,7 @@ + + #include <QObject> + #include <qgsettings.h> ++#include <QVariant> + + class GSettingsHelper : public QObject + { +@@ -31,8 +32,10 @@ public: + public: + QVariant GetLockScreenConf(QString strKey); + bool SetLockScreenConf(QString strKey, QVariant value); ++ QVariant ResetLockScreenConf(QString strKey); + QVariant GetScreenSaverConf(QString strKey); + bool SetScreenSaverConf(QString strKey, QVariant value); ++ QVariant ResetScreenSaverConf(QString strKey); + QVariant GetPowerManagerConf(QString strKey); + bool SetPowerManagerConf(QString strKey, QVariant value); + QVariant GetMateBgConf(QString strKey); +diff --git a/src/lock-backend/lightdmhelper.cpp b/src/lock-backend/lightdmhelper.cpp +index c599ac8..3033b05 100644 +--- a/src/lock-backend/lightdmhelper.cpp ++++ b/src/lock-backend/lightdmhelper.cpp +@@ -20,12 +20,12 @@ + #include <QLightDM/Greeter> + #include <QFileInfo> + #include "securityuser.h" +-#include "global_utils.h" ++#include "../../src/common/global_utils.h" + #include <pwd.h> + #include "proxymodel.h" +-#include "accountshelper.h" +-#include "definetypes.h" +-#include "uniauthservice.h" ++#include "../../src/dbusifs/accountshelper.h" ++#include "../../src/common/definetypes.h" ++#include "../../src/dbusifs/uniauthservice.h" + #include <QDBusArgument> + #include <QDBusMessage> + #include <QVariantMap> +@@ -34,7 +34,7 @@ + #include <kysec/status.h> + #endif + +-LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent) ++LightDMHelper::LightDMHelper(QSharedPointer<AccountsHelper> accountHelper, Configuration *config, QObject *parent) + : QLightDM::Greeter(parent) + , m_sessionsModel(nullptr) + , m_secUser(SecurityUser::instance()) +@@ -348,9 +348,9 @@ void LightDMHelper::initAccountsUsersInfo() + connect(userInfo.get(), &UserInfo::userPropChanged, this, &LightDMHelper::onUsersChanged); + m_mapUsers->insert(user, userInfo); + } +- connect(m_accountServiceHelper, SIGNAL(UserAdded(QDBusObjectPath)), this, SLOT(onUserAdded(QDBusObjectPath))); ++ connect(m_accountServiceHelper.get(), SIGNAL(UserAdded(QDBusObjectPath)), this, SLOT(onUserAdded(QDBusObjectPath))); + connect( +- m_accountServiceHelper, SIGNAL(UserRemoved(QDBusObjectPath)), this, SLOT(onUserRemoved(QDBusObjectPath))); ++ m_accountServiceHelper.get(), SIGNAL(UserRemoved(QDBusObjectPath)), this, SLOT(onUserRemoved(QDBusObjectPath))); + } + } + +diff --git a/src/lock-backend/lightdmhelper.h b/src/lock-backend/lightdmhelper.h +index 1530a11..1209ee9 100644 +--- a/src/lock-backend/lightdmhelper.h ++++ b/src/lock-backend/lightdmhelper.h +@@ -25,8 +25,9 @@ + #include <QList> + #include <QModelIndex> + #include <QDBusInterface> +-#include "userinfo.h" +-#include "configuration.h" ++#include "../userinfo.h" ++#include "../../src/common/configuration.h" ++#include <QSharedPointer> + + class SecurityUser; + class UsersModel; +@@ -45,7 +46,7 @@ public: + * + * @param parent 父指针 + */ +- explicit LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent = nullptr); ++ explicit LightDMHelper(QSharedPointer<AccountsHelper> accountHelper, Configuration *config, QObject *parent = nullptr); + + public: + /** +@@ -180,7 +181,7 @@ private: + QLightDM::SessionsModel *m_sessionsModel; /**< lightdm 会话数据指针 */ + QList<QString> m_listSessions; /**< 会话列表 */ + QMap<QString, UserInfoPtr> *m_mapUsers; /**< accounts 用户信息列表指针 */ +- AccountsHelper *m_accountServiceHelper = nullptr; ++ QSharedPointer<AccountsHelper> m_accountServiceHelper = nullptr; + QMap<QString, std::shared_ptr<LightDMSessionInfo>> *m_ldmSessions; + QDBusInterface *m_dbusIfsLDM; + Configuration *m_configuration = nullptr; +diff --git a/src/lock-backend/main.cpp b/src/lock-backend/main.cpp +index cd35943..409924c 100644 +--- a/src/lock-backend/main.cpp ++++ b/src/lock-backend/main.cpp +@@ -14,7 +14,7 @@ + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * +-**/ ++ **/ + #include <QCoreApplication> + #include <QDBusConnection> + #include <QDebug> +@@ -33,9 +33,13 @@ + #include "screensaveradaptor.h" + #include "personalizeddata.h" + #include "msysdbus.h" ++#include "../ukccplugins/sessiondbus/screenlockinterface.h" ++#include "../ukccplugins/sessiondbus/screensaverinterface.h" ++#include <syslog.h> + + int main(int argc, char *argv[]) + { ++ syslog(LOG_INFO, "[ukui-screensaver-backend] startup!!"); + initUkuiLog4qt("ukui-screensaver-backend"); + // 重启或关机时不被session关掉 + qunsetenv("SESSION_MANAGER"); +@@ -45,82 +49,103 @@ int main(int argc, char *argv[]) + } else { + strDisplay = QLatin1String(getenv("DISPLAY")); + } +- QString singleId = QString("ukui-screensaver-backend"+strDisplay); ++ QString singleId = QString("ukui-screensaver-backend" + strDisplay); + QtSingleCoreApplication a(singleId, argc, argv); + if (a.isRunning()) { + qDebug() << "There is an instance running"; + return 0; + } +- qInfo()<<"ukui screensaver backend Started!!"; ++ qInfo() << "ukui screensaver backend Started!!"; + // 会话管理器退出时,锁屏后端也退出 + prctl(PR_SET_PDEATHSIG, SIGKILL); +- //命令行参数解析 ++ // 命令行参数解析 + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", "Backend for the ukui ScreenSaver.")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + +- QCommandLineOption lockStartupOption(QStringLiteral("lock-startup"), +- QCoreApplication::translate("main", "lock the screen by startup")); +- parser.addOptions({lockStartupOption}); ++ QCommandLineOption lockStartupOption( ++ QStringLiteral("lock-startup"), QCoreApplication::translate("main", "lock the screen by startup")); ++ parser.addOptions({ lockStartupOption }); + parser.process(a.arguments()); + +- KYLINUSERDATAMNG::instance(); +- + // 检查该程序是否已经有实例在运行 +- QDBusInterface *checkInterface = +- new QDBusInterface("org.freedesktop.DBus", +- "/org/freedesktop/DBus", +- "org.freedesktop.DBus", +- QDBusConnection::sessionBus()); +- QDBusReply<bool> ret = checkInterface->call("NameHasOwner", +- "cn.kylinos.ScreenSaver"); +- if(ret.value()) { ++ QDBusInterface *checkInterface = new QDBusInterface( ++ "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", QDBusConnection::sessionBus()); ++ QDBusReply<bool> ret = checkInterface->call("NameHasOwner", "cn.kylinos.ScreenSaver"); ++ if (ret.value()) { + qDebug() << "There is an instance running"; + return EXIT_FAILURE; + } + + // 注册DBus +- DbusUpperInterface *interface = new DbusUpperInterface(); +- ScreenSaverAdaptor adaptor(interface); ++ syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initing!!"); ++ DbusUpperInterface interface; ++ syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface inited!!"); ++ ScreenSaverAdaptor adaptor(&interface); + + QDBusConnection service = QDBusConnection::sessionBus(); + QString sessionDbus = SS_DBUS_SERVICE; +- if(!service.registerService(sessionDbus)) { +- QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");; ++ if (!service.registerService(sessionDbus)) { ++ QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); ++ ; + sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); +- if(!service.registerService(sessionDbus)) { ++ if (!service.registerService(sessionDbus)) { + qDebug() << service.lastError().message(); + return EXIT_FAILURE; + } + } +- if(!service.registerObject(SS_DBUS_PATH, SS_DBUS_SERVICE, &adaptor, +- QDBusConnection::ExportAllSlots | +- QDBusConnection::ExportAllSignals)) { ++ if (!service.registerObject( ++ SS_DBUS_PATH, ++ SS_DBUS_SERVICE, ++ &adaptor, ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals)) { + qDebug() << service.lastError().message(); + return EXIT_FAILURE; + } ++ // 注册控制面板插件接口服务 ++ if (!isGreeterMode()) { ++ ScreenlockInterface *lockInterface = new ScreenlockInterface(&interface, &interface); ++ if (!service.registerObject( ++ SL_SESSION_DBUS_PATH, ++ lockInterface, ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllProperties ++ | QDBusConnection::ExportAllSignals)) { ++ qDebug() << service.lastError().message(); ++ return EXIT_FAILURE; ++ } ++ ScreensaverInterface *saverInterface = new ScreensaverInterface(&interface, &interface); ++ if (!service.registerObject( ++ SS_SESSION_DBUS_PATH, ++ saverInterface, ++ QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllProperties ++ | QDBusConnection::ExportAllSignals)) { ++ qDebug() << service.lastError().message(); ++ return EXIT_FAILURE; ++ } ++ } + qDebug() << service.baseService(); + +- QObject::connect(checkInterface, SIGNAL(NameLost(QString)), +- interface, SLOT(onNameLost(QString))); ++ QObject::connect(checkInterface, SIGNAL(NameLost(QString)), &interface, SLOT(onNameLost(QString))); + + if (parser.isSet(lockStartupOption)) { +- QTimer::singleShot(0, interface, [=](){ +- interface->LockStartupMode(); +- }); ++ syslog(LOG_INFO, "[ukui-screensaver-backend] lock startup mode begin!!"); ++ interface.LockStartupMode(); ++ syslog(LOG_INFO, "[ukui-screensaver-backend] lock startup mode end!!"); + } ++ interface.init(); + +- MSysDbus *m_sysDbus = new MSysDbus(interface,nullptr); ++ MSysDbus m_sysDbus(&interface); + + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); + QString sysService = "org.ukui.screensaver._" + displayNum; + if (!QDBusConnection::systemBus().registerService("org.ukui.screensaver")) { +- qDebug()<<"registerService failed"; ++ qDebug() << "registerService failed"; + } + +- QDBusConnection::systemBus().registerObject("/", "org.ukui.screensaver",m_sysDbus, QDBusConnection::ExportAllSlots); +- ++ QDBusConnection::systemBus().registerObject( ++ "/", "org.ukui.screensaver", &m_sysDbus, QDBusConnection::ExportAllSlots); ++ syslog(LOG_INFO, "[ukui-screensaver-backend] application event loop begin!!"); + return a.exec(); + } +diff --git a/src/lock-backend/pamauthenticate.cpp b/src/lock-backend/pamauthenticate.cpp +index ddf1802..a0da99f 100644 +--- a/src/lock-backend/pamauthenticate.cpp ++++ b/src/lock-backend/pamauthenticate.cpp +@@ -16,7 +16,7 @@ + * + **/ + #include "pamauthenticate.h" +-#include "global_utils.h" ++#include "../../src/common/global_utils.h" + #include "authpamthread.h" + #include <unistd.h> + #include <wait.h> +@@ -24,7 +24,7 @@ + #include <QSocketNotifier> + #include <QDebug> + +-PamAuthenticate::PamAuthenticate(LightDMHelper *helper, QObject *parent) : QObject(parent), m_lightdmHelper(helper) ++PamAuthenticate::PamAuthenticate(QSharedPointer<LightDMHelper> helper, QObject *parent) : QObject(parent), m_lightdmHelper(helper) + { + m_fdToParent[0] = -1; + m_fdToParent[1] = -1; +@@ -32,16 +32,16 @@ PamAuthenticate::PamAuthenticate(LightDMHelper *helper, QObject *parent) : QObje + m_fdToChild[1] = -1; + + connect( +- m_lightdmHelper, ++ m_lightdmHelper.get(), + SIGNAL(showMessage(QString, QLightDM::Greeter::MessageType)), + this, + SLOT(onLDMShowMessage(QString, QLightDM::Greeter::MessageType))); + connect( +- m_lightdmHelper, ++ m_lightdmHelper.get(), + SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), + this, + SLOT(onLDMShowPrompt(QString, QLightDM::Greeter::PromptType))); +- connect(m_lightdmHelper, SIGNAL(authenticationComplete()), this, SIGNAL(authenticationComplete())); ++ connect(m_lightdmHelper.get(), SIGNAL(authenticationComplete()), this, SIGNAL(authenticationComplete())); + } + + bool PamAuthenticate::inAuthentication() const +@@ -74,10 +74,14 @@ QString PamAuthenticate::authenticationUser() const + void PamAuthenticate::authenticate(const QString &username) + { + m_isOtherUser = (getenv("USER") != username); ++ + if (username == "*guest") { + m_lightdmHelper->authenticateAsGuest(); +- } else if (m_isOtherUser) ++ hasSendBiometricPam = false; ++ } else if (m_isOtherUser) { + m_lightdmHelper->authenticate(username); ++ hasSendBiometricPam = false; ++ } + else { + cancelAuthentication(); + m_strUserName = username; +@@ -93,9 +97,12 @@ void PamAuthenticate::authenticate(const QString &username) + + void PamAuthenticate::respond(const QString &response) + { +- if (m_isOtherUser) ++ if (m_isOtherUser) { ++ if (response == BIOMETRIC_IGNORE && !hasSendBiometricPam) { ++ return ; ++ } + m_lightdmHelper->respond(response); +- else { ++ } else { + m_nPrompts--; + m_responseList.push_back(response); + +@@ -276,5 +283,10 @@ void PamAuthenticate::onLDMShowMessage(QString strMsg, QLightDM::Greeter::Messag + + void PamAuthenticate::onLDMShowPrompt(QString strPrompt, QLightDM::Greeter::PromptType type) + { ++ if(strPrompt == BIOMETRIC_PAM) { ++ hasSendBiometricPam = true; ++ } else { ++ hasSendBiometricPam = false; ++ } + Q_EMIT showPrompt(strPrompt, type); + } +diff --git a/src/lock-backend/pamauthenticate.h b/src/lock-backend/pamauthenticate.h +index f5a715a..d531c2b 100644 +--- a/src/lock-backend/pamauthenticate.h ++++ b/src/lock-backend/pamauthenticate.h +@@ -22,6 +22,7 @@ + #include <QStringList> + #include <security/pam_appl.h> + #include "lightdmhelper.h" ++#include <QSharedPointer> + + typedef struct pam_message PAM_MESSAGE; + typedef struct pam_response PAM_RESPONSE; +@@ -32,7 +33,7 @@ class PamAuthenticate : public QObject + { + Q_OBJECT + public: +- explicit PamAuthenticate(LightDMHelper *helper, QObject *parent = nullptr); ++ explicit PamAuthenticate(QSharedPointer<LightDMHelper> helper, QObject *parent = nullptr); + + public: + bool inAuthentication() const; +@@ -58,7 +59,7 @@ private: + void _respond(const struct pam_response *response); + + private: +- LightDMHelper *m_lightdmHelper = nullptr; ++ QSharedPointer<LightDMHelper> m_lightdmHelper = nullptr; + bool m_isInAuthentication = false; + bool m_isAuthenticated = false; + bool m_isOtherUser = false; +@@ -70,6 +71,8 @@ private: + int m_fdToParent[2]; + int m_fdToChild[2]; + QString m_strUserName; ++ ++ bool hasSendBiometricPam = false; + }; + + #endif // PAMAUTHENTICATE_H +diff --git a/src/lock-backend/sessionwatcher.cpp b/src/lock-backend/sessionwatcher.cpp +index 7d1ef25..9f7d7fa 100644 +--- a/src/lock-backend/sessionwatcher.cpp ++++ b/src/lock-backend/sessionwatcher.cpp +@@ -20,12 +20,12 @@ + #include <QDebug> + #include <QFile> + #include <QDBusReply> +-#include "definetypes.h" +-#include "utils.h" ++#include "../../src/common/definetypes.h" ++#include "../../src/common/utils.h" + + #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" + +-SessionWatcher::SessionWatcher(GSettingsHelper *helper, QObject *parent) : QObject(parent), m_gsettingsHelper(helper) ++SessionWatcher::SessionWatcher(QSharedPointer<GSettingsHelper> helper, QObject *parent) : QObject(parent), m_gsettingsHelper(helper) + { + sessionPath = qgetenv("XDG_SESSION_PATH"); + +@@ -46,7 +46,7 @@ SessionWatcher::SessionWatcher(GSettingsHelper *helper, QObject *parent) : QObje + SLOT(onSessionRemoved(QDBusObjectPath))); + + connect( +- m_gsettingsHelper, &GSettingsHelper::lockScreenConfigChanged, this, &SessionWatcher::onLockScreenConfigChanged); ++ m_gsettingsHelper.get(), &GSettingsHelper::lockScreenConfigChanged, this, &SessionWatcher::onLockScreenConfigChanged); + // 重置屏保从不字段 + bool isEnable = m_gsettingsHelper->GetLockScreenConf(KEY_IDLE_ACTIVATION_ENABLED).toBool(); + if (!isEnable) { +diff --git a/src/lock-backend/sessionwatcher.h b/src/lock-backend/sessionwatcher.h +index 9bda7fc..bde1ae1 100644 +--- a/src/lock-backend/sessionwatcher.h ++++ b/src/lock-backend/sessionwatcher.h +@@ -25,6 +25,7 @@ + #include <QTimer> + #include <QSettings> + #include <QProcess> ++#include <QSharedPointer> + #include "gsettingshelper.h" + + class SessionWatcher : public QObject +@@ -37,14 +38,14 @@ public: + SESSION_STATUS_SCREENCLOSE = 2, // 关屏 + SESSION_STATUS_SLEEPED = 4, // 休眠/睡眠 + }; +- explicit SessionWatcher(GSettingsHelper *m_gsettingsHelper, QObject *parent = nullptr); ++ explicit SessionWatcher(QSharedPointer<GSettingsHelper> m_gsettingsHelper, QObject *parent = nullptr); + + Q_SIGNALS: + void sessionIdle(); + void sessionLockIdle(); + void sessionIdleExit(); + +-private Q_SLOTS: ++public Q_SLOTS: + void onStatusChanged(unsigned int status); + void onSessionRemoved(const QDBusObjectPath &objectPath); + void onLockScreenConfigChanged(QString strKey, QVariant value); +@@ -61,7 +62,7 @@ private: + bool lockState; + int m_nStatus = 0; // 当前状态 + QTimer *m_timerLock = nullptr; +- GSettingsHelper *m_gsettingsHelper = nullptr; ++ QSharedPointer<GSettingsHelper> m_gsettingsHelper = nullptr; + }; + + #endif // SESSIONWATCHER_H +diff --git a/src/lock-backend/switchuserutils.cpp b/src/lock-backend/switchuserutils.cpp +index 7dc55f9..06b1d5c 100644 +--- a/src/lock-backend/switchuserutils.cpp ++++ b/src/lock-backend/switchuserutils.cpp +@@ -31,7 +31,7 @@ + #include <QProcess> + #include <QStandardPaths> + #include <QString> +-#include "global_utils.h" ++#include "../../src/common/global_utils.h" + + SwitchUserUtils::SwitchUserUtils() {} + +diff --git a/src/lock-dialog/backenddbushelper.cpp b/src/lock-dialog/backenddbushelper.cpp +index eb6ff0e..979d669 100644 +--- a/src/lock-dialog/backenddbushelper.cpp ++++ b/src/lock-dialog/backenddbushelper.cpp +@@ -16,7 +16,7 @@ + * + **/ + #include "backenddbushelper.h" +-#include "definetypes.h" ++#include "../../src/common/definetypes.h" + #include <QJsonValue> + #include <QJsonObject> + #include <QJsonDocument> +@@ -1047,7 +1047,7 @@ void BackendDbusHelper::onUpdateInformation(const QString &strJson) + ParseBlockInhibitedChanged(objRes); + } break; + case LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED: { +- ParseCapslockConf(objRes); ++ ParseKeyboardConf(objRes); + } break; + case LOCK_CMD_ID_PAMAUTH_SHOWMESSAGE: { + ParsePamShowMessage(objRes); +@@ -1577,10 +1577,13 @@ bool BackendDbusHelper::ParseSessionConf(const QJsonObject &objRes) + return true; + } + +-bool BackendDbusHelper::ParseCapslockConf(const QJsonObject &objRes) ++bool BackendDbusHelper::ParseKeyboardConf(const QJsonObject &objRes) + { +- bool state = objRes.value("Value").toBool(); +- Q_EMIT capslockConfChanged(state); ++ QString strKey = objRes.value("Key").toString(); ++ if (strKey == KEY_CAPSLOCK_STATUS) { ++ bool state = objRes.value("Value").toBool(); ++ Q_EMIT capslockConfChanged(state); ++ } + return true; + } + +diff --git a/src/lock-dialog/backenddbushelper.h b/src/lock-dialog/backenddbushelper.h +index 426ab68..5b98836 100644 +--- a/src/lock-dialog/backenddbushelper.h ++++ b/src/lock-dialog/backenddbushelper.h +@@ -26,9 +26,9 @@ + #include <QtCore/QStringList> + #include <QtCore/QVariant> + #include <QtDBus/QtDBus> +-#include "userinfo.h" +-#include "agreementinfo.h" +-#include "biodefines.h" ++#include "../../src/userinfo.h" ++#include "../../src/agreementinfo.h" ++#include "../../src/common/biodefines.h" + + /** + * @brief 后端服务访问工具类 +@@ -422,7 +422,7 @@ private: + bool ParseUkccPluginsConf(const QJsonObject &objRes); + bool ParseThemeStyleConf(const QJsonObject &objRes); + bool ParseSessionConf(const QJsonObject &objRes); +- bool ParseCapslockConf(const QJsonObject &objRes); ++ bool ParseKeyboardConf(const QJsonObject &objRes); + + void ParsePamShowMessage(const QJsonObject &objRes); + void ParsePamShowPrompt(const QJsonObject &objRes); +diff --git a/src/lock-dialog/languagesetting.cpp b/src/lock-dialog/languagesetting.cpp +index 75c43b2..1d9ae64 100644 +--- a/src/lock-dialog/languagesetting.cpp ++++ b/src/lock-dialog/languagesetting.cpp +@@ -17,7 +17,7 @@ + **/ + #include "languagesetting.h" + #include <QApplication> +-#include "definetypes.h" ++#include "../../src/common/definetypes.h" + #include <QDebug> + #include <QFileInfo> + #include <QProcess> +diff --git a/src/lock-dialog/lockdialogmodel.cpp b/src/lock-dialog/lockdialogmodel.cpp +index e0bcf16..e3e558e 100644 +--- a/src/lock-dialog/lockdialogmodel.cpp ++++ b/src/lock-dialog/lockdialogmodel.cpp +@@ -24,8 +24,8 @@ + #include <QStandardPaths> + #include <QApplication> + #include <QScreen> +-#include "utils.h" +-#include "definetypes.h" ++#include "../../src/common/utils.h" ++#include "../../src/common/definetypes.h" + #include <pwd.h> + + LockDialogModel::LockDialogModel(QObject *parent) +diff --git a/src/lock-dialog/lockdialogmodel.h b/src/lock-dialog/lockdialogmodel.h +index 8db3e16..a44175c 100644 +--- a/src/lock-dialog/lockdialogmodel.h ++++ b/src/lock-dialog/lockdialogmodel.h +@@ -19,10 +19,10 @@ + #define LOCKDIALOGMODEL_H + + #include <QObject> +-#include "userinfo.h" +-#include "agreementinfo.h" +-#include "screensavermode.h" +-#include "biodefines.h" ++#include "../../src/userinfo.h" ++#include "../../src/agreementinfo.h" ++#include "../../src/widgets/screensavermode.h" ++#include "../../src/common/biodefines.h" + + /** + * @brief 锁屏模型类(管理所有功能逻辑和状态) +diff --git a/src/lock-dialog/lockdialogperformer.cpp b/src/lock-dialog/lockdialogperformer.cpp +index 8a5afeb..e254f0d 100644 +--- a/src/lock-dialog/lockdialogperformer.cpp ++++ b/src/lock-dialog/lockdialogperformer.cpp +@@ -18,6 +18,7 @@ + #include "lockdialogperformer.h" + #include "lockdialogmodel.h" + #include "backenddbushelper.h" ++#include "../common/plasma-shell-manager.h" + #include "utils.h" + #include "rsac.h" + +@@ -58,11 +59,13 @@ void LockDialogPerformer::initConnections() + m_modelLockDialog->updateSleepLockcheck(m_bdHelper->getSleepLockcheck()); + m_modelLockDialog->updateShutdownLockcheck(m_bdHelper->getShutdownLockcheck()); + }); +- connect( +- m_bdHelper, +- &BackendDbusHelper::capslockConfChanged, +- m_modelLockDialog, +- &LockDialogModel::onCapslockStateChanged); ++ if (!m_modelLockDialog->isUseWayland()) { ++ connect( ++ m_bdHelper, ++ &BackendDbusHelper::capslockConfChanged, ++ m_modelLockDialog, ++ &LockDialogModel::onCapslockStateChanged); ++ } + + connect( + m_bdHelper, +@@ -231,3 +234,14 @@ void LockDialogPerformer::initData() + m_modelLockDialog->updateSessionLogoutMusic(m_bdHelper->getSessionConf(KEY_SESSION_LOGOUT_MUSIC).toBool()); + m_modelLockDialog->updateSessionPoweroffMusic(m_bdHelper->getSessionConf(KEY_SESSION_POWEROFF_MUSIC).toBool()); + } ++ ++void LockDialogPerformer::initExtraData() ++{ ++ if (m_modelLockDialog->isUseWayland()) { ++ connect( ++ PlasmaShellManager::getInstance(), ++ &PlasmaShellManager::capslockStateChanged, ++ m_modelLockDialog, ++ &LockDialogModel::onCapslockStateChanged); ++ } ++} +diff --git a/src/lock-dialog/lockdialogperformer.h b/src/lock-dialog/lockdialogperformer.h +index 903507b..c4d8f7e 100644 +--- a/src/lock-dialog/lockdialogperformer.h ++++ b/src/lock-dialog/lockdialogperformer.h +@@ -39,6 +39,8 @@ public: + */ + explicit LockDialogPerformer(LockDialogModel *model, QObject *parent = nullptr); + ++ void initExtraData(); ++ + private: + /** + * @brief 初始化连接信号槽 +diff --git a/src/lock-dialog/main.cpp b/src/lock-dialog/main.cpp +index 2e75af6..0f6ebc9 100644 +--- a/src/lock-dialog/main.cpp ++++ b/src/lock-dialog/main.cpp +@@ -30,6 +30,7 @@ + #include <QEventLoop> + #include <signal.h> + #include <unistd.h> ++#include <sys/prctl.h> + #include <QProcess> + #include <ukui-log4qt.h> + #include <QtSingleApplication> +@@ -65,13 +66,13 @@ int main(int argc, char *argv[]) + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + #endif + // 屏蔽输入法 +-// qunsetenv("QT_IM_MODULE"); ++ qunsetenv("QT_IM_MODULE"); + +- LockDialogModel *lockDialogModel = new LockDialogModel(); +- LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel); ++ LockDialogModel lockDialogModel; ++ LockDialogPerformer performer(&lockDialogModel); + +- if (isGreeterMode() && !lockDialogModel->isUseWayland()) { +- DisplayService::instance(lockDialogModel)->setCurUserName(lockDialogModel->defaultUserName()); ++ if (isGreeterMode() && !lockDialogModel.isUseWayland()) { ++ DisplayService::instance(&lockDialogModel)->setCurUserName(lockDialogModel.defaultUserName()); + } + + QString strDisplay = ""; +@@ -82,14 +83,17 @@ int main(int argc, char *argv[]) + } + QString id = QString("ukui-screensaver-dialog" + strDisplay); + QtSingleApplication app(id, argc, argv); ++ // 锁屏后端退出时,锁屏前端也退出 ++ prctl(PR_SET_PDEATHSIG, SIGKILL); + ++ performer.initExtraData(); + LockDialogModel::CommandLineArgs cmdArgs; +- if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) { ++ if (!lockDialogModel.parseCmdArguments(app.arguments(), cmdArgs)) { + return 0; + } + + if (!isGreeterMode()) { +- // 需要判断参数是否是session-tools ++ // 需要判断参数是否是session-tools + if (!cmdArgs.isSessionTools) { + // 试用模式不起锁屏 + checkIslivecd(); +@@ -99,12 +103,10 @@ int main(int argc, char *argv[]) + if (app.isRunning()) { + QString strArguments = QApplication::arguments().join(","); + app.sendMessage(strArguments); +- delete lockDialogModel; +- lockDialogModel = nullptr; + qInfo() << "ukui screensaver dialog is running!"; + return EXIT_SUCCESS; + } +- if (!lockDialogModel->isUseWayland()) { ++ if (!lockDialogModel.isUseWayland()) { + setCursorCenter(); + } + // 加载插件实例 +@@ -114,22 +116,22 @@ int main(int argc, char *argv[]) + + QApplication::setSetuidAllowed(true); + +- QObject::connect(lockDialogModel, &LockDialogModel::requestUnlockSession, [=]() { ++ QObject::connect(&lockDialogModel, &LockDialogModel::requestUnlockSession, [=]() { + if (window) { + window->onCloseScreensaver(); + } else { + exit(0); + } + }); +- if (!lockDialogModel->sessionActive()) { ++ if (!lockDialogModel.sessionActive()) { + QEventLoop *loopTemp = new QEventLoop(&app); +- QObject::connect(lockDialogModel, &LockDialogModel::sessionActiveChanged, [loopTemp](bool isActive) { ++ QObject::connect(&lockDialogModel, &LockDialogModel::sessionActiveChanged, [loopTemp](bool isActive) { + qDebug() << "sessionActiveChanged:" << isActive; + if (isActive && loopTemp->isRunning()) { + loopTemp->quit(); + } + }); +- QObject::connect(lockDialogModel, &LockDialogModel::requestLockSession, [loopTemp]() { ++ QObject::connect(&lockDialogModel, &LockDialogModel::requestLockSession, [loopTemp]() { + qDebug() << "session requestLock!"; + if (loopTemp->isRunning()) { + loopTemp->quit(); +@@ -139,19 +141,19 @@ int main(int argc, char *argv[]) + } + + QObject::connect( +- &app, SIGNAL(messageReceived(const QString &)), lockDialogModel, SLOT(onRunningMessage(const QString &))); ++ &app, SIGNAL(messageReceived(const QString &)), &lockDialogModel, SLOT(onRunningMessage(const QString &))); + + qInfo() << "Start " << app.arguments(); + + // 加载翻译文件 +- UserInfoPtr ptrUserInfo = lockDialogModel->findUserByName(lockDialogModel->defaultUserName()); ++ UserInfoPtr ptrUserInfo = lockDialogModel.findUserByName(lockDialogModel.defaultUserName()); + if (ptrUserInfo) { + LanguageSetting::instance()->onLanguageChanged(ptrUserInfo->lang()); + } else { + LanguageSetting::instance()->onLanguageChanged(QLocale::system().name()); + } + +- window = new FullBackgroundWidget(lockDialogModel); ++ window = new FullBackgroundWidget(&lockDialogModel, cmdArgs.isLockStartup); + + // 注册DBus + ScreenSaverWndAdaptor adaptorWnd(window); +@@ -159,7 +161,6 @@ int main(int argc, char *argv[]) + QString sessionDbus = SSWND_DBUS_SERVICE; + if (!service.registerService(SSWND_DBUS_SERVICE)) { + QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); +- ; + sessionDbus = QString("%1%2").arg(QString(SSWND_DBUS_SERVICE)).arg(displayNum); + if (!service.registerService(sessionDbus)) { + qDebug() << service.lastError().message(); +@@ -177,7 +178,7 @@ int main(int argc, char *argv[]) + qDebug() << service.baseService(); + + if (cmdArgs.isBlank) { +- Q_EMIT lockDialogModel->showBlankScreensaver(cmdArgs.nBlankDelay, cmdArgs.isBlankHasLock); ++ Q_EMIT lockDialogModel.showBlankScreensaver(cmdArgs.nBlankDelay, cmdArgs.isBlankHasLock); + } + + #ifndef USE_INTEL +@@ -188,42 +189,42 @@ int main(int argc, char *argv[]) + #endif + + if (cmdArgs.isLock) { +- Q_EMIT lockDialogModel->showLock(false); ++ Q_EMIT lockDialogModel.showLock(false); + } + + if (cmdArgs.isLockStartup) { +- Q_EMIT lockDialogModel->showLock(true); ++ Q_EMIT lockDialogModel.showLock(true); + } + + if (cmdArgs.isSessionIdle) { +- Q_EMIT lockDialogModel->showSessionIdle(); ++ Q_EMIT lockDialogModel.showSessionIdle(); + } + + if (cmdArgs.isLockScreensaver) { +- Q_EMIT lockDialogModel->showLockScreensaver(); ++ Q_EMIT lockDialogModel.showLockScreensaver(); + } + + if (cmdArgs.isScreenSaver) { +- Q_EMIT lockDialogModel->showScreensaver(); ++ Q_EMIT lockDialogModel.showScreensaver(); + } + + if (cmdArgs.isSessionTools) { +- Q_EMIT lockDialogModel->showSessionTools(); ++ Q_EMIT lockDialogModel.showSessionTools(); + } + + if (cmdArgs.isAppBlock != -1) { +- Q_EMIT lockDialogModel->showAppBlockWindow(cmdArgs.isAppBlock); ++ Q_EMIT lockDialogModel.showAppBlockWindow(cmdArgs.isAppBlock); + } + + if (cmdArgs.isMultiUserBlock != -1) { +- Q_EMIT lockDialogModel->showMultiUsersBlockWindow(cmdArgs.isMultiUserBlock); ++ Q_EMIT lockDialogModel.showMultiUsersBlockWindow(cmdArgs.isMultiUserBlock); + } + + if (cmdArgs.isSwitchUser) { +- Q_EMIT lockDialogModel->showSwitchUserLock(); ++ Q_EMIT lockDialogModel.showSwitchUserLock(); + } + + KillFocusOfKydroid(); +- ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] application event loop begin!!"); + return app.exec(); + } +diff --git a/src/lock-dialog/pam-tally.c b/src/lock-dialog/pam-tally.c +index a1d1014..f02d9f6 100644 +--- a/src/lock-dialog/pam-tally.c ++++ b/src/lock-dialog/pam-tally.c +@@ -41,6 +41,7 @@ struct tallylog { + uint64_t fail_time; /* time of last failure */ + }; + ++static pam_tally g_tally_info; + + static + int get_is_open_other_authentication() +@@ -150,6 +151,19 @@ void set_shm_tally_real() + + int pam_tally_init() + { ++#if 1 ++ int deny = 0, unlock_time = 0 , root_unlock_time = 0; ++ if (!get_pam_tally(&deny, &unlock_time,&root_unlock_time)) { ++ return 0; ++ } ++ g_tally_info.deny = deny; ++ g_tally_info.unlock_time = unlock_time; ++ g_tally_info.failed = 0; ++ g_tally_info.lock_start_time = 0; ++ g_tally_info.root_unlock_time = root_unlock_time; ++ ++ return 1; ++#else + int fd; + int deny = 0, unlock_time = 0 , root_unlock_time = 0; + pam_tally *tally_ptr; +@@ -197,6 +211,7 @@ int pam_tally_init() + tally_ptr->root_unlock_time = root_unlock_time; + + return 1; ++#endif + } + + static +@@ -389,10 +404,12 @@ void get_tally(uid_t uid, int *tfile, struct tallylog *tally) + int pam_tally_unlock_time_left(uid_t userID, int *fail_cnt,int *left_time, int *deny, int *fail_time, int *unlock_time1) + { + pam_tally *tally_ptr; +- ++#if 1 ++ tally_ptr = &g_tally_info; ++#else + if((tally_ptr = pam_tally_memory()) == NULL) + return 0; +- ++#endif + int unlock_time = tally_ptr->unlock_time; + *deny = tally_ptr->deny; + +@@ -441,9 +458,12 @@ int pam_tally_root_unlock_time_left(uid_t userID, int *fail_cnt,int *left_time, + { + + pam_tally *tally_ptr; +- if((tally_ptr = pam_tally_memory()) == NULL){ +- return 0; +- } ++#if 1 ++ tally_ptr = &g_tally_info; ++#else ++ if((tally_ptr = pam_tally_memory()) == NULL) ++ return 0; ++#endif + int root_unlock_time = tally_ptr->root_unlock_time; + int deny = tally_ptr->deny; + if(root_unlock_time == 0) +diff --git a/src/ukccplugins/CMakeLists.txt b/src/ukccplugins/CMakeLists.txt +new file mode 100644 +index 0000000..9599549 +--- /dev/null ++++ b/src/ukccplugins/CMakeLists.txt +@@ -0,0 +1,3 @@ ++add_definitions(-DOPENKYLIN -DNile) ++add_subdirectory(screenlock) ++add_subdirectory(screensaver) +diff --git a/src/ukccplugins/screenlock/CMakeLists.txt b/src/ukccplugins/screenlock/CMakeLists.txt +new file mode 100644 +index 0000000..2941a16 +--- /dev/null ++++ b/src/ukccplugins/screenlock/CMakeLists.txt +@@ -0,0 +1,47 @@ ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(GIO2.0 REQUIRED gio-2.0) ++pkg_check_modules(KYSDKQTWIDGETS REQUIRED kysdk-qtwidgets) ++pkg_check_modules(KYSDKDIAGNOSTICS REQUIRED kysdk-diagnostics) ++ ++include_directories(${PROJECT_BINARY_DIR}) ++include_directories(${PROJECT_SOURCE_DIR}/Common) ++ ++include_directories( ++ ${QGS_INCLUDE_DIRS} ++ ${GIO2.0_INCLUDE_DIRS} ++ ${KYSDKQTWIDGETS_INCLUDE_DIRS} ++ ${KYSDKDIAGNOSTICS_INCLUDE_DIRS} ++ /usr/include/ukcc ++ ) ++ ++set(EXTRA_LIBS ++ ${EXTRA_LIBS} ++ ${QGS_LIBRARIES} ++ ${GIO2.0_LIBRARIES} ++ ${KYSDKQTWIDGETS_LIBRARIES} ++ ${KYSDKDIAGNOSTICS_LIBRARIES} ++ -lukcc ++ ) ++ ++qt5_add_resources(lockscreen_Plugin_SRC ++ ) ++ ++qt5_wrap_cpp(lockscreen_Plugin_SRC ++ pictureunit.h ++ screenlock.h ++ screenlockui.h ++ ) ++ ++set(lockscreen_Plugin_SRC ++ ${lockscreen_Plugin_SRC} ++ pictureunit.cpp ++ screenlock.cpp ++ screenlockui.cpp ++ ) ++ ++add_library(screenlock SHARED ${lockscreen_Plugin_SRC}) ++target_link_libraries(screenlock Qt5::Widgets Qt5::DBus Qt5::Xml ${EXTRA_LIBS}) ++ ++install(TARGETS ++ screenlock ++ DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-control-center) +diff --git a/src/ukccplugins/screenlock/pictureunit.cpp b/src/ukccplugins/screenlock/pictureunit.cpp +new file mode 100644 +index 0000000..4628b78 +--- /dev/null ++++ b/src/ukccplugins/screenlock/pictureunit.cpp +@@ -0,0 +1,124 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 "pictureunit.h" ++#include <QApplication> ++#include <widgets/maskwidget.h> ++#include <QTouchEvent> ++#include <QGSettings> ++#include <QDebug> ++#include <qmath.h> ++ ++PictureUnit::PictureUnit(QWidget *parent) : QLabel(parent) ++{ ++ _filename = ""; ++ ++ hoverStyleSheet = QString("border-width: 3px;border-style: solid;border-color: palette(highlight);"); ++ clickedStyleSheet = QString("border-width: 4px;border-style: solid;border-color: palette(highlight);"); ++ if (QGSettings::isSchemaInstalled("org.ukui.style")) { ++ QGSettings *qtSettings = new QGSettings("org.ukui.style", QByteArray(), this); ++ connect(qtSettings, &QGSettings::changed, this, [=](const QString &key) { ++ if (key == "themeColor" && this->clickedFlag) { ++ this->setStyleSheet(clickedStyleSheet); ++ } ++ }); ++ } ++ clickedFlag = false; ++ setAttribute(Qt::WA_DeleteOnClose); ++ setFixedSize(QSize(198, 136)); ++ setScaledContents(true); ++ ++ MaskWidget *maskWidget = new MaskWidget(this); ++ maskWidget->setGeometry(0, 0, this->width(), this->height()); ++ isTouchControl = false; ++ qApp->installEventFilter(this); ++ this->setAttribute(Qt::WA_AcceptTouchEvents); ++} ++ ++PictureUnit::~PictureUnit() {} ++ ++void PictureUnit::setFilenameText(QString fn) ++{ ++ _filename = fn; ++} ++ ++QString PictureUnit::filenameText() ++{ ++ return _filename; ++} ++ ++void PictureUnit::mouseReleaseEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::LeftButton && !isTouchControl && e->pos().x() >= 0 && e->pos().y() >= 0 ++ && e->pos().x() <= width() && e->pos().y() <= height()) { ++ ++ changeClickedFlag(true); ++ Q_EMIT clicked(_filename); ++ } ++} ++ ++void PictureUnit::enterEvent(QEvent *e) ++{ ++ if (getClickedFlag() == false && !isTouchControl) { ++ 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; ++ if (flag) { ++ this->setFrameShape(QFrame::Box); ++ this->setStyleSheet(clickedStyleSheet); ++ } else { ++ this->setStyleSheet("border-width: 0px;"); ++ } ++} ++ ++bool PictureUnit::eventFilter(QObject *w, QEvent *e) ++{ ++ if (w == this) { ++ if (e->type() == QEvent::TouchBegin) { ++ isTouchControl = true; ++ QTouchEvent *touchE = static_cast<QTouchEvent *>(e); ++ touchBeginPoint = touchE->touchPoints().at(0).screenPos(); ++ } ++ } else if (e->type() == QEvent::TouchEnd && isTouchControl) { ++ isTouchControl = false; ++ QTouchEvent *touchE = static_cast<QTouchEvent *>(e); ++ touchEndPoint = touchE->touchPoints().at(0).screenPos(); ++ if (qFabs(touchEndPoint.x() - touchBeginPoint.x()) < 1.0 ++ && qFabs(touchEndPoint.y() - touchBeginPoint.y()) < 1.0) { ++ emit clicked(_filename); ++ } ++ } ++ return qApp->eventFilter(w, e); ++} +diff --git a/src/ukccplugins/screenlock/pictureunit.h b/src/ukccplugins/screenlock/pictureunit.h +new file mode 100644 +index 0000000..e334b86 +--- /dev/null ++++ b/src/ukccplugins/screenlock/pictureunit.h +@@ -0,0 +1,61 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 PICTUREUNIT_H ++#define PICTUREUNIT_H ++ ++#include <QLabel> ++#include <QMouseEvent> ++#include <QEvent> ++ ++class PictureUnit : public QLabel ++{ ++ Q_OBJECT ++ ++public: ++ explicit PictureUnit(QWidget *parent = nullptr); ++ ~PictureUnit(); ++ ++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 mouseReleaseEvent(QMouseEvent * e); ++ bool eventFilter(QObject *w, QEvent *e); ++ ++private: ++ bool clickedFlag; ++ QString hoverStyleSheet; ++ bool isTouchControl; ++ QPointF touchBeginPoint; ++ QPointF touchEndPoint; ++ ++Q_SIGNALS: ++ void clicked(QString filename); ++ ++}; ++ ++#endif // PICTUREUNIT_H +diff --git a/src/ukccplugins/screenlock/screenlock.cpp b/src/ukccplugins/screenlock/screenlock.cpp +new file mode 100644 +index 0000000..9a9f150 +--- /dev/null ++++ b/src/ukccplugins/screenlock/screenlock.cpp +@@ -0,0 +1,277 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 "screenlock.h" ++#include <interface/ukcccommon.h> ++using namespace ukcc; ++#include <QDebug> ++#include <QDir> ++#include <QFileDialog> ++#include <QDesktopServices> ++#include <QProcess> ++#include <QFileSystemWatcher> ++#include <QTranslator> ++#include <QLocale> ++#include <QApplication> ++ ++Screenlock::Screenlock() : mFirstLoad(true) ++{ ++ QTranslator *translator = new QTranslator(this); ++ translator->load("/usr/share/ukui-screensaver/ukccplugins/i18n_qm/" + QLocale::system().name()); ++ QApplication::installTranslator(translator); ++ ++ pluginName = tr("Screenlock"); ++ pluginType = PERSONALIZED; ++} ++ ++Screenlock::~Screenlock() {} ++ ++QString Screenlock::plugini18nName() ++{ ++ return pluginName; ++} ++ ++int Screenlock::pluginTypes() ++{ ++ return pluginType; ++} ++ ++QWidget *Screenlock::pluginUi() ++{ ++ if (mFirstLoad) { ++ mFirstLoad = false; ++ screenlockui = new ScreenlockUi(); ++ screenlockInterface = new QDBusInterface( ++ "org.ukui.ScreenSaver", ++ "/Screenlock", ++ "org.ukui.ScreenSaver.session.Screenlock", ++ QDBusConnection::sessionBus(), ++ this); ++ if (screenlockInterface->isValid()) { // 判断服务是否存在 ++ QDBusMessage message = screenlockInterface->call("ping"); // 判断dbus路径是否存在 ++ if (message.type() == QDBusMessage::ErrorMessage ++ && message.errorMessage().contains("No such object path", Qt::CaseInsensitive)) { ++ qWarning() << screenlockInterface << ":" << message.errorMessage(); ++ } else { ++ QDBusConnection::sessionBus().connect( ++ "org.ukui.ScreenSaver", ++ "/Screenlock", ++ "org.ukui.ScreenSaver.session.Screenlock", ++ "changed", ++ this, ++ SLOT(dataChanged(QString))); ++ initContent(); ++ connectUiSignals(); ++ connectToServer(); ++ } ++ } else { ++ qCritical() << "org.ukui.ScreenSaver.session.Screenlock DBus error:" << screenlockInterface->lastError(); ++ } ++ } else { ++ screenlockui->resize(screenlockui->size() - QSize(1, 1)); ++ screenlockui->resize(screenlockui->size() + QSize(1, 1)); ++ } ++ return screenlockui; ++} ++ ++const QString Screenlock::name() const ++{ ++ return QStringLiteral("Screenlock"); ++} ++ ++bool Screenlock::isShowOnHomePage() const ++{ ++ return true; ++} ++ ++QIcon Screenlock::icon() const ++{ ++ return QIcon::fromTheme("ukui-lock-screen-symbolic"); ++} ++ ++bool Screenlock::isEnable() const ++{ ++ return true; ++} ++ ++void Screenlock::dataChanged(const QString &key) ++{ ++ if (toChangeKey != key) { ++ if (key == "showOnLogin") { ++ initShowOnLogin(); ++ } else if (key == "wallpaper") { ++ initWallpaper(); ++ } ++ } ++ toChangeKey = ""; ++} ++ ++void Screenlock::initContent() ++{ ++ QStringList previewPictures = screenlockInterface->property("previewWallpapers").toStringList(); ++ QStringList sourcePictures = screenlockInterface->property("sourceWallpapers").toStringList(); ++ screenlockui->setPictures(previewPictures, sourcePictures); ++ initWallpaper(); ++ initShowOnLogin(); ++} ++ ++void Screenlock::initShowOnLogin() ++{ ++ screenlockui->setShowOnLogin(screenlockInterface->property("showOnLogin").toBool()); ++} ++ ++void Screenlock::initWallpaper() ++{ ++ screenlockui->setPicture(screenlockInterface->property("wallpaper").toString()); ++} ++ ++void Screenlock::connectUiSignals() ++{ ++ connect(screenlockui, &ScreenlockUi::showOnLoginChanged, this, [=](bool b) { ++ toChangeKey = "showOnLogin"; ++ screenlockInterface->call("setShowOnLogin", b); ++ UkccCommon::buriedSettings( ++ name(), ++ QString("Show picture of screenlock on screenlogin"), ++ QString("settings"), ++ UkccCommon::boolToString(b)); ++ }); ++ connect(screenlockui, &ScreenlockUi::pictureChanged, this, [=](QString file) { ++ toChangeKey = "wallpaper"; ++ screenlockInterface->call("setWallpaper", file); ++ }); ++ connect(screenlockui, &ScreenlockUi::localButtonClicked, this, [=]() { showLocalWpDialog(); }); ++ connect(screenlockui, &ScreenlockUi::onlineButtonClicked, this, [=]() { ++ QDesktopServices::openUrl(QUrl(QLatin1String("https://www.ubuntukylin.com/wallpaper.html"))); ++ UkccCommon::buriedSettings(name(), QString("onlineBtnonlineButton"), QString("clicked")); ++ }); ++ connect(screenlockui, &ScreenlockUi::resetButtonClicked, this, [=]() { ++ screenlockInterface->call("resetDefault"); ++ UkccCommon::buriedSettings(name(), QString("resetBtn"), QString("clicked")); ++ }); ++ connect(screenlockui, &ScreenlockUi::toSetMonitor, this, [=]() { ++ UkccCommon::buriedSettings(name(), "setBtn(Monitor Off)", QString("clicked")); ++ QProcess::startDetached( ++ "ukui-control-center", ++ QStringList() << "-m" ++ << "Power"); ++ }); ++ connect(screenlockui, &ScreenlockUi::toSetScreensaver, this, [=]() { ++ UkccCommon::buriedSettings(name(), "setBtn(Screensaver)", QString("clicked")); ++ QProcess::startDetached( ++ "ukui-control-center", ++ QStringList() << "-m" ++ << "Screensaver"); ++ }); ++} ++ ++void Screenlock::showLocalWpDialog() ++{ ++ QStringList filters; ++ filters << tr("Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)"); ++ QFileDialog fd; ++ ++ QList<QUrl> 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<QUrl> 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<char *>(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")); ++ ++ fd.setSidebarUrls(usb_list + mntUrlList); ++ ++ 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); ++ ++ screenlockInterface->call("setWallpaper", selectedfile); ++ UkccCommon::buriedSettings(name(), QString("browserLocalwpBtn"), QString("clicked")); ++} ++ ++void Screenlock::connectToServer() ++{ ++ QThread *NetThread = new QThread; ++ MThread *NetWorker = new MThread; ++ NetWorker->moveToThread(NetThread); ++ connect(NetThread, &QThread::started, NetWorker, &MThread::run); ++ connect(NetWorker, &MThread::keychangedsignal, this, &Screenlock::keyChangedSlot); ++ connect(NetThread, &QThread::finished, NetWorker, &MThread::deleteLater); ++ NetThread->start(); ++} ++ ++void Screenlock::keyChangedSlot(const QString &key) ++{ ++ if (key == "ukui-screensaver") { ++ if (!bIsCloudService) { ++ bIsCloudService = true; ++ } ++ initShowOnLogin(); ++ initWallpaper(); ++ } ++} +diff --git a/src/ukccplugins/screenlock/screenlock.h b/src/ukccplugins/screenlock/screenlock.h +new file mode 100644 +index 0000000..9cf0808 +--- /dev/null ++++ b/src/ukccplugins/screenlock/screenlock.h +@@ -0,0 +1,83 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 SCREENLOCK_H ++#define SCREENLOCK_H ++ ++#include <interface/mthread.h> ++#include <interface/interface.h> ++#include "screenlockui.h" ++#include <QObject> ++#include <QtPlugin> ++ ++#ifdef signals ++#undef signals ++#endif ++ ++#include <glib.h> ++#include <gio/gio.h> ++ ++class Screenlock : public QObject, CommonInterface ++{ ++ Q_OBJECT ++ Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface") ++ Q_INTERFACES(CommonInterface) ++ ++public: ++ Screenlock(); ++ ~Screenlock(); ++ ++ QString plugini18nName() Q_DECL_OVERRIDE; ++ int pluginTypes() Q_DECL_OVERRIDE; ++ QWidget * pluginUi() Q_DECL_OVERRIDE; ++ const QString name() const Q_DECL_OVERRIDE; ++ bool isShowOnHomePage() const Q_DECL_OVERRIDE; ++ QIcon icon() const Q_DECL_OVERRIDE; ++ bool isEnable() const Q_DECL_OVERRIDE; ++ virtual QString translationPath() const { ++ return QStringLiteral("/usr/share/ukui-screensaver/ukccplugins/i18n/%1.ts"); ++ } ++ ++private: ++ void connectToServer(); ++ ++public Q_SLOTS: ++ void keyChangedSlot(const QString &key); ++ ++public: ++ void initContent(); ++ void initShowOnLogin(); ++ void initWallpaper(); ++ void connectUiSignals(); ++ void showLocalWpDialog(); ++ ++public Q_SLOTS: ++ void dataChanged(const QString &key); ++ ++private: ++ QString toChangeKey; ++ QString pluginName; ++ int pluginType; ++ bool mFirstLoad; ++ ScreenlockUi *screenlockui = nullptr; ++ QDBusInterface *screenlockInterface = nullptr; ++ bool bIsCloudService = false; ++}; ++ ++#endif // SCREENLOCK_H +diff --git a/src/ukccplugins/screenlock/screenlockui.cpp b/src/ukccplugins/screenlock/screenlockui.cpp +new file mode 100644 +index 0000000..4431aaa +--- /dev/null ++++ b/src/ukccplugins/screenlock/screenlockui.cpp +@@ -0,0 +1,713 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 "screenlockui.h" ++#include <QImageReader> ++#include <QScrollArea> ++#include <QScrollBar> ++ ++ScreenlockUi::ScreenlockUi() ++{ ++ setAttribute(Qt::WA_DeleteOnClose); ++ m_screenlockLayout = new QVBoxLayout(this); ++ m_screenlockLayout->setContentsMargins(0,0,0,0); ++ initUi(); ++} ++ ++ScreenlockUi::~ScreenlockUi() ++{ ++ ++} ++ ++void ScreenlockUi::initUi() ++{ ++ initScreenLock(); ++#ifdef Nile ++ initLeavLockStatus(); ++#endif ++ initSignals(); ++} ++ ++void ScreenlockUi::initScreenLock() ++{ ++ // 1 锁屏 ++ m_wallpaperTitleLabel = new KLabel(this); ++ m_wallpaperTitleLabel->setContentsMargins(16, 0, 0, 0); ++ //~ contents_path /Screenlock/Screenlock ++ m_wallpaperTitleLabel->setText(tr("Screenlock")); ++ ++ // 2.1 预览图 ++ m_previewFrame = new UkccFrame(this); ++ m_previewFrame->setFixedHeight(193); ++ m_previewLayout = new QHBoxLayout(m_previewFrame); ++ m_previewLayout->setContentsMargins(16, 12, 16, 16); ++ ++ m_previewLabel = new QLabel(this); ++ m_previewLabel->setFixedSize(280, 160); ++ m_centerGroup = new SettingGroup(this); ++ ++ m_contentBackgroundGroup = new KBackgroundGroup(m_previewFrame); ++ QList<QWidget*> contentList; ++ ++ // 登录界面显示锁屏壁纸 ++ QWidget* showPicWidget = new QWidget(); ++ QHBoxLayout* typeLayout = new QHBoxLayout(showPicWidget); ++ typeLayout->setContentsMargins(16, 0, 0, 0); ++ typeLayout->setSpacing(0); ++ //~ contents_path /Screenlock/Show picture of screenlock on screenlogin ++ QLabel* showPicLabel = new QLabel(tr("Show picture of screenlock on screenlogin"), showPicWidget); ++ m_showPicSwitchButton = new KSwitchButton(showPicWidget); ++ typeLayout->addWidget(showPicLabel); ++ typeLayout->addStretch(); ++ typeLayout->addWidget(m_showPicSwitchButton); ++ contentList.append(showPicWidget); ++ ++#ifdef Nile ++ // 动态锁 ++ QWidget* btLeaveLockWidget = new QWidget(); ++ QHBoxLayout* btLeaveLockLayout = new QHBoxLayout(btLeaveLockWidget); ++ btLeaveLockLayout->setContentsMargins(16, 0, 0, 0); ++ btLeaveLockLayout->setSpacing(0); ++ QLabel* btLeaveLockLabel = new QLabel(tr("Leave lock (System will be locked when the paired phone gone)"), btLeaveLockWidget); ++ m_btLeaveLockSwitchButton = new KSwitchButton(btLeaveLockWidget); ++ btLeaveLockLayout->addWidget(btLeaveLockLabel); ++ btLeaveLockLayout->addStretch(); ++ btLeaveLockLayout->addWidget(m_btLeaveLockSwitchButton); ++ contentList.append(btLeaveLockWidget); ++ ++ // 蓝牙设备 ++ m_bluetoothWidget = new QWidget(); ++ KLabel* bluetoothLabel = new KLabel(m_bluetoothWidget); ++ bluetoothLabel->setText(tr("Specified device")); ++ m_bluetoothComboBox = new QComboBox(m_bluetoothWidget); ++ QHBoxLayout* bluetoothLayout = new QHBoxLayout(m_bluetoothWidget); ++ bluetoothLayout->setContentsMargins(16, 0, 0, 0); ++ bluetoothLayout->setSpacing(0); ++ bluetoothLayout->addWidget(bluetoothLabel); ++ bluetoothLayout->addStretch(); ++ bluetoothLayout->addWidget(m_bluetoothComboBox); ++ m_bluetoothWidget->setVisible(false); ++ contentList.append(m_bluetoothWidget); ++ ++ // 无配对手机去设置蓝牙 ++ m_setBtWidget = new QWidget(); ++ QHBoxLayout* setBtLayout = new QHBoxLayout(m_setBtWidget); ++ setBtLayout->setContentsMargins(16, 0, 0, 0); ++ setBtLayout->setSpacing(0); ++ KLabel* setBtLabel = new KLabel(m_setBtWidget); ++ setBtLabel->setText(tr("No paired phone. Please turn to 'Bluetooth' to pair.")); ++ QLabel* setBticonLabel = new QLabel(m_setBtWidget); ++ QIcon icon = QIcon::fromTheme("kylin-dialog-warning"); ++ if (icon.isNull()) { ++ icon = QIcon::fromTheme("dialog-warning"); ++ } ++ setBticonLabel->setPixmap(icon.pixmap(16, 16)); ++ m_setBtPushButton = new KPushButton(m_setBtWidget); ++ m_setBtPushButton->setText(tr("Bluetooth")); ++ setBtLayout->addWidget(setBticonLabel); ++ setBtLayout->addWidget(setBtLabel); ++ setBtLayout->addStretch(); ++ setBtLayout->addWidget(m_setBtPushButton); ++ m_setBtWidget->setVisible(false); ++ contentList.append(m_setBtWidget); ++ ++ m_noBtWidget = new UkccFrame(m_centerGroup, UkccFrame::None,true); ++ contentList.append(m_noBtWidget); ++#endif ++ m_contentBackgroundGroup->addWidgetList(contentList); ++ ++ // 预览区域滚动条设置 ++ QScrollArea *previewScrollArea = new QScrollArea; ++ previewScrollArea->setFixedHeight(192); ++ previewScrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground); ++ previewScrollArea->setStyleSheet("QScrollArea{background-color: transparent;}"); ++ previewScrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false); ++ previewScrollArea->verticalScrollBar()->setEnabled(false); ++ previewScrollArea->setWidgetResizable(true); ++ previewScrollArea->setWidget(m_previewFrame); ++ ++ QVBoxLayout* rightPreviewLayout = new QVBoxLayout(); ++ rightPreviewLayout->setContentsMargins(8, 0, 16, 0); ++ rightPreviewLayout->setSpacing(0); ++ rightPreviewLayout->addWidget(m_contentBackgroundGroup); ++ rightPreviewLayout->addStretch(); ++ ++ m_previewLayout->addWidget(m_previewLabel); ++ m_previewLayout->addSpacing(0); ++ m_previewLayout->addLayout(rightPreviewLayout); ++ ++ m_picBtnFrame = new UkccFrame(m_centerGroup); ++ m_picBtnFrame->setLineWidth(0); ++ ++ m_pictureFrame = new UkccFrame(m_picBtnFrame); ++ m_pictureFrame->setLineWidth(0); ++ ++ m_pictureLayout = new FlowLayout(m_pictureFrame, 8, -1, -1); ++ m_pictureLayout->setContentsMargins(16, 0, 16, 0); ++ ++ m_bottomFrame = new UkccFrame(m_picBtnFrame); ++ ++ // 3.1 选择图片 ++ //~ contents_path /Wallpaper/Choose Picture ++ QLabel* chooseLabel = new QLabel(tr("Choose Picture"), m_bottomFrame); ++ ++ // 3.2 本地图片 ++ //~ contents_path /Screenlock/Local Pictures ++ m_localBtn = new QPushButton(tr("Local Pictures"), m_bottomFrame); ++ ++ // 3.3 在线图片 ++ //~ contents_path /Screenlock/Online Pictures ++ m_onlineBtn = new QPushButton(tr("Online Pictures"), m_bottomFrame); ++ ++ // 3.4 恢复默认 ++ //~ contents_path /Screenlock/Reset To Default ++ m_resetBtn = new QPushButton(tr("Reset To Default"), m_bottomFrame); ++ ++ m_bottomLayout = new QHBoxLayout(m_bottomFrame); ++ m_bottomLayout->setContentsMargins(16, 8, 16, 8); ++ m_bottomLayout->addWidget(chooseLabel); ++ m_bottomLayout->addStretch(); ++ m_bottomLayout->addWidget(m_localBtn); ++ m_bottomLayout->addWidget(m_onlineBtn); ++ m_bottomLayout->addWidget(m_resetBtn); ++ ++ // 相关设置 ++ m_relateFrame = new UkccFrame(m_picBtnFrame); ++ m_relateLayout = new QVBoxLayout(m_relateFrame); ++ UkccFrame* titleFrame = new UkccFrame(); ++ QHBoxLayout* relateTitleLayout = new QHBoxLayout(titleFrame); ++ ++ relateTitleLayout->setContentsMargins(0, 0, 0, 0); ++ relateTitleLabel = new KLabel(m_relateFrame); ++ relateTitleLabel->setContentsMargins(16, 0, 0, 0); ++ relateTitleLayout->addWidget(relateTitleLabel); ++ relateTitleLabel->setText(tr("Related Settings")); ++ ++ KBackgroundGroup* relateGroup = new KBackgroundGroup(); ++ monitorWidget = new PushButtonWidget(tr("Monitor Off"), m_relateFrame); ++ monitorWidget->setButtonText(tr("Set")); ++ screensaverWidget = new PushButtonWidget(tr("Screensaver"), m_relateFrame); ++ screensaverWidget->setButtonText(tr("Set")); ++ ++ relateGroup->addWidget(titleFrame); ++ relateGroup->addWidget(monitorWidget); ++ relateGroup->addWidget(screensaverWidget); ++ ++ m_relateLayout->addWidget(relateGroup); ++ ++ m_picBtnLayout = new QVBoxLayout(m_picBtnFrame); ++ m_picBtnLayout->setMargin(0); ++ m_picBtnLayout->setSpacing(0); ++ m_picBtnLayout->addWidget(m_bottomFrame); ++ m_picBtnLayout->addWidget(m_pictureFrame); ++ m_picBtnLayout->addWidget(m_relateFrame); ++ ++ m_centerGroup->addWidget(m_picBtnFrame); ++ ++ QScrollArea *contentScrollArea = new QScrollArea; ++ contentScrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground); ++ contentScrollArea->setStyleSheet("QScrollArea{background-color: transparent;}"); ++ contentScrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false); ++ contentScrollArea->setWidgetResizable(true); ++ contentScrollArea->setFrameShape(QFrame::Box); ++ contentScrollArea->setFrameShadow(QFrame::Plain); ++ contentScrollArea->setWidget(m_centerGroup); ++ ++ m_screenlockLayout->addWidget(m_wallpaperTitleLabel); ++ m_screenlockLayout->addWidget(previewScrollArea); ++ m_screenlockLayout->addWidget(contentScrollArea); ++ ++#ifdef Nile ++ QHBoxLayout *noBtVLayout = new QHBoxLayout(); ++ QLabel *noBtWarnIcon = new QLabel(m_noBtWidget); ++ QLabel *noBtMessage = new QLabel(tr("No bluetooth adapter detected, can not use Leave Lock."),m_noBtWidget); ++ ++ noBtWarnIcon->setPixmap(icon.pixmap(18,18)); ++ noBtVLayout->setContentsMargins(16, 0, 16, 0); ++ noBtVLayout->setSpacing(16); ++ noBtVLayout->addWidget(noBtWarnIcon); ++ noBtVLayout->addWidget(noBtMessage,Qt::AlignLeft); ++ m_noBtWidget->setLayout(noBtVLayout); ++ m_noBtWidget->setVisible(false); ++ ++ m_bluetoothWidget->setVisible(false); ++#endif ++} ++ ++void ScreenlockUi::initLeavLockStatus() { ++ bool ispowered = isBluetoothPowered(); ++ bool leaveLockOn = getLeavLockOn(); ++ bool hasAdapter = hasBluetoothAdapter(); ++ QMap<QString, QString> btDevices = getBtPairedDevices(); ++ ++ m_bluetoothComboBox->clear(); ++ ++ if (leaveLockOn) { ++ m_btLeaveLockSwitchButton->click(); ++ } ++ ++ canLeaveLock = !btDevices.isEmpty(); ++ m_bluetoothComboBox->addItem(tr("Please select device")); ++ for (auto dev : btDevices.keys()) { ++ m_bluetoothComboBox->addItem(btDevices.value(dev), dev); ++ } ++ if (canLeaveLock && ispowered) { ++ lockdev = getLeaveLockDev(); ++ if (!lockdev.isEmpty() && canLeaveLock) { ++ m_bluetoothComboBox->setCurrentIndex(m_bluetoothComboBox->findData(lockdev)); ++ } ++ } ++ if (!hasAdapter && leaveLockOn) { ++ m_noBtWidget->setVisible(!hasAdapter); ++ return; ++ } ++ if (m_bluetoothComboBox->count() == 1 && leaveLockOn) { ++ m_setBtWidget->setVisible(true); ++ m_noBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(false); ++ return; ++ } ++ m_bluetoothWidget->setVisible(leaveLockOn && canLeaveLock && ispowered); ++ m_setBtWidget->setVisible((!canLeaveLock || !ispowered) && leaveLockOn); ++} ++ ++void ScreenlockUi::setBtPushButtonClickSlot() { ++ QProcess *process = new QProcess(); ++ QString cmd = "ukui-control-center"; ++ QStringList arg; ++ arg.clear(); ++ arg << "-m"; ++ arg << "Bluetooth"; ++ process->startDetached(cmd,arg); ++} ++ ++void ScreenlockUi::btLeaveLockButtonClickSlot(bool clicked) { ++ if (!clicked) { ++ m_noBtWidget->setVisible(false); ++ m_setBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(false); ++ if (!lockdev.isEmpty()) { ++ setLeaveLock(false); ++ } ++ lockdev.clear(); ++ m_bluetoothComboBox->setCurrentIndex(0); ++ return; ++ } ++ m_bluetoothComboBox->setCurrentIndex(0); ++ bool ispowered = isBluetoothPowered(); ++ bool hasAdapter = hasBluetoothAdapter(); ++ ++ if (!hasAdapter) { ++ m_noBtWidget->setVisible(!hasAdapter); ++ return; ++ } ++ if (m_bluetoothComboBox->count() == 1) { ++ m_setBtWidget->setVisible(true); ++ ++ m_noBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(false); ++ return; ++ } ++ m_bluetoothWidget->setVisible(canLeaveLock && ispowered); ++ m_setBtWidget->setVisible(!canLeaveLock || !ispowered); ++} ++ ++void ScreenlockUi::bluetoothWidgetIdxChangeSlot(int index) { ++ if (!lockdev.isEmpty()) { ++ setLeaveLock(false); ++ } ++ if (index == 0) { ++ lockdev.clear(); ++ return; ++ } ++ lockdev = m_bluetoothComboBox->currentData().toString(); ++ setLeaveLock(true); ++} ++ ++void ScreenlockUi::initSignals() ++{ ++ connect(m_showPicSwitchButton, &KSwitchButton::clicked, this, [=](){ ++ Q_EMIT showOnLoginChanged(m_showPicSwitchButton->isChecked()); ++ }); ++#ifdef Nile ++ connect(m_btLeaveLockSwitchButton, &KSwitchButton::clicked, this, [=](bool clicked){ ++ btLeaveLockButtonClickSlot(clicked); ++ }); ++ ++ connect(m_bluetoothComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) { ++ bluetoothWidgetIdxChangeSlot(index); ++ }); ++ ++ connect(m_setBtPushButton, &QPushButton::clicked, this, [=](){ ++ setBtPushButtonClickSlot(); ++ }); ++#endif ++ connect(monitorWidget, &PushButtonWidget::clicked, this, [=](){ ++ Q_EMIT toSetMonitor(); ++ }); ++ connect(screensaverWidget, &PushButtonWidget::clicked, this, [=](){ ++ Q_EMIT toSetScreensaver(); ++ }); ++ connect(m_localBtn, &QPushButton::clicked, this, [=](){ ++ Q_EMIT localButtonClicked(); ++ }); ++ connect(m_onlineBtn, &QPushButton::clicked, this, [=](){ ++ Q_EMIT onlineButtonClicked(); ++ }); ++ connect(m_resetBtn, &QPushButton::clicked, this, [=](){ ++ Q_EMIT resetButtonClicked(); ++ }); ++#ifdef Nile ++ QDBusConnection::sessionBus().connect("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "devPairSignal", ++ this, ++ SLOT(addPairedDev(QString,bool))); ++ ++ QDBusConnection::sessionBus().connect("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "defaultAdapterPowerChanged", ++ this, ++ SLOT(powerChanged(bool))); ++ ++ QDBusConnection::sessionBus().connect("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "defaultAdapterChanged", ++ this, ++ SLOT(defaultAdapterChanged(QString))); ++ ++ QDBusConnection::sessionBus().connect("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "adapterAddSignal", ++ this, ++ SLOT(adapterAdded(QString))); ++ ++ QDBusConnection::sessionBus().connect("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "adapterRemoveSignal", ++ this, ++ SLOT(adapterRemoved(QString))); ++#endif ++} ++ ++void ScreenlockUi::setShowOnLogin(bool b) ++{ ++ m_showPicSwitchButton->blockSignals(true); ++ m_showPicSwitchButton->setChecked(b); ++ m_showPicSwitchButton->blockSignals(false); ++} ++ ++void ScreenlockUi::setPicture(const QString &data) ++{ ++ currentFile = data; ++ QImageReader reader(data); ++ reader.setDecideFormatFromContent(true); ++ m_previewLabel->setPixmap(QPixmap::fromImage(reader.read()).scaled(m_previewLabel->size())); ++ resetClickedPic(); ++} ++ ++void ScreenlockUi::setPictures(const QStringList &picturePathList, const QStringList &sourcePathList) ++{ ++ if (picturePathList.size() != sourcePathList.size()) { ++ qWarning()<<"picturePathList.size():"<<picturePathList.size()<<" != sourcePathList.size():"<<sourcePathList.size(); ++ return; ++ } ++ ++ for (int i = 0; i < picturePathList.size(); ++i) { ++ QPixmap pixmap; ++ pixmap.load(picturePathList.at(i)); ++ bool clicked = false; ++ if (sourcePathList.at(i) == currentFile) { ++ clicked = true; ++ } ++ createPictureUnit(pixmap, sourcePathList.at(i), clicked); ++ } ++} ++ ++void ScreenlockUi::createPictureUnit(const QPixmap &pixmap, const QString &filename, const bool &clicked) ++{ ++ PictureUnit *picUnit = new PictureUnit(this); ++ picUnit->setPixmap(pixmap); ++ picUnit->setFilenameText(filename); ++ if (clicked) { ++ prePictureUnit = picUnit; ++ picUnit->changeClickedFlag(true); ++ setPicture(filename); ++ } ++ connect(picUnit, &PictureUnit::clicked, [=](QString file){ ++ if (prePictureUnit) { ++ prePictureUnit->changeClickedFlag(false); ++ } ++ prePictureUnit = picUnit; ++ setPicture(file); ++ Q_EMIT pictureChanged(file); ++ }); ++ m_pictureLayout->addWidget(picUnit); ++} ++ ++void ScreenlockUi::resetClickedPic() { ++ if (prePictureUnit != nullptr) { ++ prePictureUnit->changeClickedFlag(false); ++ prePictureUnit = nullptr; ++ } ++ for (int i = m_pictureLayout->count() - 1; i >= 0; --i) { ++ QLayoutItem *it = m_pictureLayout->itemAt(i); ++ PictureUnit *picUnit = static_cast<PictureUnit*>(it->widget()); ++ if (currentFile == picUnit->filenameText()) { ++ picUnit->changeClickedFlag(true); ++ prePictureUnit = picUnit; ++ } ++ } ++} ++ ++QMap<QString, QString> ScreenlockUi::getBtPairedDevices() { ++ QMap<QString, QString> pairedList; ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getPairedPhoneAddr"); ++ ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) ++ { ++ QStringList ret = response.arguments().takeFirst().toStringList(); ++ if (ret.isEmpty()) ++ return pairedList; ++ for (int i = 0; i < ret.size(); i++) { ++ if (pairedList.contains(ret.at(i))) ++ continue; ++ QDBusMessage _message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getDevName"); ++ _message << ret.at(i); ++ QDBusMessage _response = QDBusConnection::sessionBus().call(_message); ++ if (_response.type() == QDBusMessage::ReplyMessage) ++ { ++ QString devName = _response.arguments().takeFirst().toString(); ++ if (devName == "") ++ continue; ++ pairedList.insert(ret.at(i), devName); ++ } ++ } ++ } ++ return pairedList; ++} ++ ++bool ScreenlockUi::hasBluetoothAdapter() { ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", \ ++ "getAdapterDevAddressList"); ++ ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) { ++ QStringList ret = response.arguments().takeFirst().toStringList(); ++ return !ret.isEmpty(); ++ } else ++ return false; ++} ++ ++bool ScreenlockUi::isBluetoothPowered() { ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getDefaultAdapterPower"); ++ ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) { ++ return response.arguments().takeFirst().toBool(); ++ } else ++ return false; ++} ++ ++void ScreenlockUi::addPairedDev(QString dev, bool paired) { ++ int index = m_bluetoothComboBox->findData(dev); ++ if (paired && index >= 0) ++ return; ++ ++ if (!paired && index >= 0) { ++ m_bluetoothComboBox->removeItem(m_bluetoothComboBox->findData(dev)); ++ if (m_bluetoothComboBox->count() == 1) { ++ m_noBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(false); ++ m_setBtWidget->setVisible(true); ++ } ++ if (lockdev == dev) ++ lockdev.clear(); ++ return; ++ } ++ ++ QDBusMessage _message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getDevName"); ++ _message << dev; ++ QDBusMessage _response = QDBusConnection::sessionBus().call(_message); ++ if (_response.type() == QDBusMessage::ReplyMessage) ++ { ++ QString devName = _response.arguments().takeFirst().toString(); ++ if (devName != "") { ++ m_bluetoothComboBox->addItem(devName, dev); ++ m_setBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(true); ++ } ++ } ++} ++ ++void ScreenlockUi::powerChanged(bool powered) { ++ if (!m_btLeaveLockSwitchButton->isChecked()) ++ return; ++ if (!hasBluetoothAdapter()) { ++ m_noBtWidget->setVisible(true); ++ m_setBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(false); ++ return; ++ } ++ ++ m_noBtWidget->setVisible(false); ++ m_setBtWidget->setVisible(!powered); ++ m_bluetoothWidget->setVisible(powered); ++ setLeaveLock(false); ++} ++ ++void ScreenlockUi::setLeaveLock(bool on) { ++ if (lockdev.isEmpty()) ++ return; ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "setLeaveLock"); ++ message << lockdev << on; ++ QDBusConnection::sessionBus().call(message); ++} ++ ++bool ScreenlockUi::getLeavLockOn() { ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getLeaveLock"); ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) ++ return response.arguments().takeFirst().toBool(); ++ else ++ return false; ++} ++ ++QString ScreenlockUi::getLeaveLockDev() { ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", ++ "getLeaveLockDev"); ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) ++ return response.arguments().takeFirst().toString(); ++ else ++ return QString(""); ++} ++ ++void ScreenlockUi::defaultAdapterChanged(QString address) { ++ Q_UNUSED(address); ++ if (!m_btLeaveLockSwitchButton->isChecked()) ++ return; ++ bool ispowered = isBluetoothPowered(); ++ bool leaveLockOn = getLeavLockOn(); ++ bool hasAdapter = hasBluetoothAdapter(); ++ QMap<QString, QString> btDevices = getBtPairedDevices(); ++ ++ lockdev.clear(); ++ m_bluetoothComboBox->clear(); ++ ++ if (leaveLockOn && !m_btLeaveLockSwitchButton->isChecked()) { ++ m_btLeaveLockSwitchButton->click(); ++ } ++ ++ canLeaveLock = !btDevices.isEmpty(); ++ m_bluetoothComboBox->addItem(tr("Please select device")); ++ for (auto dev : btDevices.keys()) ++ m_bluetoothComboBox->addItem(btDevices.value(dev), dev); ++ ++ if (!hasAdapter && leaveLockOn) { ++ m_noBtWidget->setVisible(!hasAdapter); ++ return; ++ } ++ m_bluetoothWidget->setVisible(leaveLockOn && canLeaveLock && ispowered); ++ m_setBtWidget->setVisible((!canLeaveLock || !ispowered) && leaveLockOn); ++} ++ ++void ScreenlockUi::adapterAdded(QString address) { ++ Q_UNUSED(address); ++ if (!m_btLeaveLockSwitchButton->isChecked()) ++ return; ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", \ ++ "getAdapterDevAddressList"); ++ ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) { ++ QStringList ret = response.arguments().takeFirst().toStringList(); ++ if (ret.size() > 1) ++ return; ++ else { ++ bool ispowered = isBluetoothPowered(); ++ QMap<QString, QString> btDevices = getBtPairedDevices(); ++ ++ lockdev.clear(); ++ m_bluetoothComboBox->clear(); ++ ++ canLeaveLock = !btDevices.isEmpty(); ++ m_bluetoothComboBox->addItem(tr("Please select device")); ++ for (auto dev : btDevices.keys()) { ++ m_bluetoothComboBox->addItem(btDevices.value(dev), dev); ++ } ++ m_noBtWidget->setVisible(false); ++ m_setBtWidget->setVisible(false); ++ m_bluetoothWidget->setVisible(canLeaveLock && ispowered); ++ m_setBtWidget->setVisible(!canLeaveLock || !ispowered); ++ } ++ } ++} ++ ++void ScreenlockUi::adapterRemoved(QString address) { ++ Q_UNUSED(address); ++ if (!m_btLeaveLockSwitchButton->isChecked()) ++ return; ++ QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth", ++ "/com/ukui/bluetooth", ++ "com.ukui.bluetooth", \ ++ "getAdapterDevAddressList"); ++ ++ QDBusMessage response = QDBusConnection::sessionBus().call(message); ++ if (response.type() == QDBusMessage::ReplyMessage) { ++ QStringList ret = response.arguments().takeFirst().toStringList(); ++ if (ret.size() < 1){ ++ lockdev.clear(); ++ m_bluetoothComboBox->clear(); ++ m_noBtWidget->setVisible(true); ++ m_bluetoothWidget->setVisible(false); ++ m_setBtWidget->setVisible(false); ++ } ++ } ++} +diff --git a/src/ukccplugins/screenlock/screenlockui.h b/src/ukccplugins/screenlock/screenlockui.h +new file mode 100644 +index 0000000..349bd0f +--- /dev/null ++++ b/src/ukccplugins/screenlock/screenlockui.h +@@ -0,0 +1,123 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2019 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 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 SCREENLOCKUI_H ++#define SCREENLOCKUI_H ++ ++#include <widgets/settinggroup.h> ++#include <widgets/flowlayout.h> ++#include <widgets/switchwidget.h> ++#include <widgets/comboxwidget.h> ++#include <widgets/pushbuttonwidget.h> ++#include <QProcess> ++#include "pictureunit.h" ++#include <QHBoxLayout> ++#include <QWidget> ++#include <kysdk/applications/klabel.h> ++#include <kysdk/applications/kbackgroundgroup.h> ++ ++using namespace kdk; ++ ++class ScreenlockUi : public QWidget ++{ ++ Q_OBJECT ++public: ++ ScreenlockUi(); ++ ~ScreenlockUi(); ++ void setShowOnLogin(bool b); ++ void setPicture(const QString &data); ++ void setPictures(const QStringList &picturePathList, const QStringList &sourcePathList); ++ void createPictureUnit(const QPixmap &pixmap, const QString &filename, const bool &clicked); ++ void resetClickedPic(); ++ ++private: ++ void initUi(); ++ void initScreenLock(); ++ void initSignals(); ++ void initLeavLockStatus(); ++ bool hasBluetoothAdapter(); ++ bool isBluetoothPowered(); ++ bool getLeavLockOn(); ++ QString getLeaveLockDev(); ++ QMap<QString, QString> getBtPairedDevices(); ++ ++private slots: ++ void addPairedDev(QString dev, bool paired); ++ void powerChanged(bool powered); ++ void setLeaveLock(bool on); ++ void defaultAdapterChanged(QString address); ++ void adapterAdded(QString address); ++ void adapterRemoved(QString address); ++ void setBtPushButtonClickSlot(); ++ void btLeaveLockButtonClickSlot(bool clicked); ++ void bluetoothWidgetIdxChangeSlot(int index); ++ ++private: ++ QVBoxLayout *m_uiLayout = nullptr; ++ QVBoxLayout *m_screenlockLayout = nullptr; ++ QVBoxLayout *m_relateLayout = nullptr; ++ ++private: ++ KLabel *m_wallpaperTitleLabel = nullptr; ++ UkccFrame *m_previewFrame = nullptr; ++ QHBoxLayout *m_previewLayout = nullptr; ++ QLabel *m_previewLabel = nullptr; ++ SettingGroup *m_centerGroup = nullptr; ++ UkccFrame *m_noBtWidget = nullptr; ++ UkccFrame *m_picBtnFrame = nullptr; ++ QVBoxLayout *m_picBtnLayout = nullptr; ++ UkccFrame *m_pictureFrame = nullptr; ++ FlowLayout *m_pictureLayout = nullptr; ++ UkccFrame *m_bottomFrame = nullptr; ++ QHBoxLayout *m_bottomLayout = nullptr; ++ QPushButton *m_localBtn = nullptr; ++ QPushButton *m_onlineBtn = nullptr; ++ QPushButton *m_resetBtn = nullptr; ++ KSwitchButton* m_showPicSwitchButton = nullptr; ++ KSwitchButton* m_btLeaveLockSwitchButton = nullptr; ++ KPushButton* m_setBtPushButton = nullptr; ++ QWidget* m_setBtWidget = nullptr; ++ UkccFrame* m_relateFrame = nullptr; ++ QWidget* m_bluetoothWidget = nullptr; ++ QComboBox* m_bluetoothComboBox = nullptr; ++ KBackgroundGroup* m_contentBackgroundGroup = nullptr; ++private: ++ KLabel *relateTitleLabel = nullptr; ++ SettingGroup *relatedGroup = nullptr; ++ PushButtonWidget *monitorWidget = nullptr; ++ PushButtonWidget *screensaverWidget = nullptr; ++ ++private: ++ PictureUnit *prePictureUnit = nullptr; ++ bool canLeaveLock = false; ++ QString currentFile; ++ QString lockdev; ++ ++Q_SIGNALS: ++ void showOnLoginChanged(const bool &b); ++ void pictureChanged(const QString &picture); ++ void localButtonClicked(); ++ void onlineButtonClicked(); ++ void resetButtonClicked(); ++ void toSetMonitor(); ++ void toSetScreensaver(); ++}; ++ ++ ++#endif // SCREENLOCKUI_H +diff --git a/src/ukccplugins/screensaver/CMakeLists.txt b/src/ukccplugins/screensaver/CMakeLists.txt +new file mode 100644 +index 0000000..35fc567 +--- /dev/null ++++ b/src/ukccplugins/screensaver/CMakeLists.txt +@@ -0,0 +1,51 @@ ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(GIO2.0 REQUIRED gio-2.0) ++pkg_check_modules(GIOUNIX2.0 REQUIRED gio-unix-2.0) ++pkg_check_modules(KYSDKQTWIDGETS REQUIRED kysdk-qtwidgets) ++pkg_check_modules(KYSDKDIAGNOSTICS REQUIRED kysdk-diagnostics) ++ ++include_directories(${PROJECT_BINARY_DIR}) ++include_directories(${PROJECT_SOURCE_DIR}/Common) ++ ++include_directories( ++ ${QGS_INCLUDE_DIRS} ++ ${GIO2.0_INCLUDE_DIRS} ++ ${GIOUNIX2.0_INCLUDE_DIRS} ++ ${KYSDKQTWIDGETS_INCLUDE_DIRS} ++ ${KYSDKDIAGNOSTICS_INCLUDE_DIRS} ++ /usr/include/ukcc ++ ) ++ ++set(EXTRA_LIBS ++ ${EXTRA_LIBS} ++ ${QGS_LIBRARIES} ++ ${GIO2.0_LIBRARIES} ++ ${GIOUNIX2.0_LIBRARIES} ++ ${KYSDKQTWIDGETS_LIBRARIES} ++ ${KYSDKDIAGNOSTICS_LIBRARIES} ++ -lukcc ++ ) ++ ++qt5_add_resources(screensaver_Plugin_SRC ++ ) ++ ++qt5_wrap_cpp(screensaver_Plugin_SRC ++ previewwidget.h ++ screensaver.h ++ screensaverpluginso.h ++ screensaverui.h ++ ) ++ ++set(screensaver_Plugin_SRC ++ ${screensaver_Plugin_SRC} ++ previewwidget.cpp ++ screensaver.cpp ++ screensaverui.cpp ++ ) ++ ++add_library(screensaver SHARED ${screensaver_Plugin_SRC}) ++target_link_libraries(screensaver Qt5::Widgets Qt5::DBus ${EXTRA_LIBS}) ++ ++install(TARGETS ++ screensaver ++ DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-control-center) +diff --git a/src/ukccplugins/screensaver/previewwidget.cpp b/src/ukccplugins/screensaver/previewwidget.cpp +new file mode 100644 +index 0000000..e865fdf +--- /dev/null ++++ b/src/ukccplugins/screensaver/previewwidget.cpp +@@ -0,0 +1,35 @@ ++#include "previewwidget.h" ++#include <QProcess> ++ ++PreviewWidget::PreviewWidget(QWidget *parent):QWidget(parent) ++{ ++ ++} ++ ++PreviewWidget::~PreviewWidget() ++{ ++ ++} ++ ++void PreviewWidget::paintEvent(QPaintEvent *event) ++{ ++ Q_UNUSED(event); ++ ++ QPainter p(this); ++ p.setPen(Qt::NoPen); ++ p.setBrush(Qt::black); ++ p.drawRect(rect()); ++} ++ ++void PreviewWidget::mousePressEvent(QMouseEvent *e) ++{ ++ if(e->button() == Qt::LeftButton) { ++ previewScreensaver(); ++ } ++} ++ ++void PreviewWidget::previewScreensaver() ++{ ++ static QProcess *viewProcess = new QProcess(); ++ viewProcess->start("ukui-screensaver-command --screensaver"); ++} +diff --git a/src/ukccplugins/screensaver/previewwidget.h b/src/ukccplugins/screensaver/previewwidget.h +new file mode 100644 +index 0000000..96fbf3f +--- /dev/null ++++ b/src/ukccplugins/screensaver/previewwidget.h +@@ -0,0 +1,22 @@ ++#ifndef PREVIEWWIDGET_H ++#define PREVIEWWIDGET_H ++#include <QWidget> ++#include <QPainter> ++#include <QMouseEvent> ++ ++class PreviewWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ PreviewWidget(QWidget *parent = nullptr); ++ ~PreviewWidget(); ++ void previewScreensaver(); ++ ++protected: ++ void paintEvent(QPaintEvent *e); ++ ++private: ++ void mousePressEvent(QMouseEvent *e); ++}; ++ ++#endif // PREVIEWWIDGET_H +diff --git a/src/ukccplugins/screensaver/screensaver.cpp b/src/ukccplugins/screensaver/screensaver.cpp +new file mode 100644 +index 0000000..37acf50 +--- /dev/null ++++ b/src/ukccplugins/screensaver/screensaver.cpp +@@ -0,0 +1,379 @@ ++/* -*- 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 "screensaver.h" ++#include <QDebug> ++#include <QtConcurrent/QtConcurrent> ++#include <QTranslator> ++#include <QLocale> ++#include <QApplication> ++ ++#define PREENTRY_TIME "preentryTime" ++#define SCREENSAVER_TYPE "screensaverType" ++#define SHOWTIME_UKUI "showBreakTimeUkui" ++#define SHOWTIME_CUSTOM "showBreakTimeCustom" ++#define SCREENLOCK_ENABLED "screenLockEnabled" ++#define CUSTOM_PATH "customPath" ++#define SWITCH_RANDOW "switchRandom" ++#define CYCLE_TIME "cycleTime" ++#define CUSTOM_TEXT "customText" ++#define CUSTOM_TEXT_CENTERED "customTextCentered" ++ ++Screensaver::Screensaver() : mFirstLoad(true) ++{ ++ QTranslator *translator = new QTranslator(this); ++ translator->load("/usr/share/ukui-screensaver/ukccplugins/i18n_qm/" + QLocale::system().name()); ++ QApplication::installTranslator(translator); ++ ++ pluginName = tr("Screensaver"); ++ pluginType = PERSONALIZED; ++ QtConcurrent::run([=] { preInitialize(); }); ++} ++ ++Screensaver::~Screensaver() ++{ ++ if (!mFirstLoad) { ++ screensaverUi->deleteLater(); ++ screensaverUi = nullptr; ++ } ++} ++ ++QString Screensaver::plugini18nName() ++{ ++ return pluginName; ++} ++ ++int Screensaver::pluginTypes() ++{ ++ return pluginType; ++} ++ ++void Screensaver::preInitialize() ++{ ++ screensaverInterface = new QDBusInterface( ++ "org.ukui.ScreenSaver", ++ "/Screensaver", ++ "org.ukui.ScreenSaver.session.Screensaver", ++ QDBusConnection::sessionBus(), ++ this); ++ if (!screensaverInterface->isValid()) { ++ qCritical() << "org.ukui.ScreenSaver.session.ScreenSaver DBus error:" << screensaverInterface->lastError(); ++ return; ++ } ++ QDBusMessage message = screensaverInterface->call("ping"); // 判断dbus路径是否存在 ++ if (message.type() == QDBusMessage::ErrorMessage ++ && message.errorMessage().contains("No such object path", Qt::CaseInsensitive)) { ++ qCritical() << screensaverInterface << ":" << message.errorMessage(); ++ return; ++ } ++ ++ QPluginLoader pluginLoader("/usr/lib/ukui-screensaver/libscreensaver-default.so"); ++ pluginLoader.load(); ++ QObject *plugin = pluginLoader.instance(); ++ screensaverPtr = nullptr; ++ if (plugin) { ++ screensaverPtr = std::unique_ptr<ScreensaverPlugin>(qobject_cast<ScreensaverPlugin *>(plugin)); ++ } else { ++ qWarning() << "pluginLoader '/usr/lib/ukui-screensaver/libscreensaver-default.so' failed"; ++ } ++} ++ ++QWidget *Screensaver::pluginUi() ++{ ++ if (mFirstLoad) { ++ mFirstLoad = false; ++ screensaverUi = new ScreensaverUi; ++ initOptions(); ++ initContent(); ++ connectUiSignals(); ++ connectToServer(); ++ } ++ return screensaverUi; ++} ++ ++const QString Screensaver::name() const ++{ ++ return QStringLiteral("Screensaver"); ++} ++ ++void Screensaver::plugin_leave() ++{ ++ return; ++} ++ ++bool Screensaver::isShowOnHomePage() const ++{ ++ return true; ++} ++ ++QIcon Screensaver::icon() const ++{ ++ return QIcon::fromTheme("ukui-screensaver-symbolic"); ++} ++ ++bool Screensaver::isEnable() const ++{ ++ return true; ++} ++ ++void Screensaver::dataChanged(const QString &key) ++{ ++ if (key != toChangeKey) { ++ if (key == PREENTRY_TIME) { ++ initIdleTime(); ++ } else if (key == SCREENSAVER_TYPE) { ++ initScreensaver(); ++ } else if (key == CUSTOM_PATH) { ++ initCustomSource(); ++ } else if (key == SWITCH_RANDOW) { ++ initSwicthMode(); ++ } else if (key == CYCLE_TIME) { ++ initSwitchTime(); ++ } else if (key == CUSTOM_TEXT) { ++ initCustomText(); ++ } else if (key == CUSTOM_TEXT_CENTERED) { ++ initTextPosition(); ++ } else if (key == SHOWTIME_UKUI) { ++ initShowBreakTimeUkui(); ++ } else if (key == SHOWTIME_CUSTOM) { ++ initShowBreakTimeCustom(); ++ } else if (key == SCREENLOCK_ENABLED) { ++ initLockscreen(); ++ } ++ } ++ toChangeKey = ""; ++} ++ ++void Screensaver::initOptions() ++{ ++ QStringList textList = {}; ++ QList<int> dataList = {}; ++ QStringList dataList2 = {}; ++ ++ textList.clear(); ++ textList << tr("5min") << tr("10min") << tr("15min") << tr("30min") << tr("1hour") << tr("Never"); ++ ++ dataList.clear(); ++ dataList << 5 << 10 << 15 << 30 << 60 << -1; ++ ++#ifdef OPENKYLIN ++ textList.insert(0, tr("1min")); ++ dataList.insert(0, 1); ++#endif ++ screensaverUi->setIdleTimeOptions(textList, dataList); ++ ++ textList.clear(); ++ textList << tr("UKUI") << tr("Customize"); ++ dataList2.clear(); ++ dataList2 << "ukui" ++ << "custom"; ++ screensaverUi->setScreensaverOptions(textList, dataList2); ++ ++ textList.clear(); ++ textList << tr("1min") << tr("5min") << tr("10min") << tr("30min"); ++ dataList.clear(); ++ dataList << 60 << 300 << 600 << 1800; ++ screensaverUi->setSwitchTimeOptions(textList, dataList); ++} ++ ++void Screensaver::initContent() ++{ ++ initIdleTime(); ++ initScreensaver(); ++ initCustomSource(); ++ initSwicthMode(); ++ initSwitchTime(); ++ initCustomText(); ++ initTextPosition(); ++ initShowBreakTimeUkui(); ++ initShowBreakTimeCustom(); ++ initLockscreen(); ++} ++ ++void Screensaver::initPreview() ++{ ++ if (screensaverPtr) { ++ qInfo() << "screensaverPtr can be used"; ++ QWidget *widget = screensaverPtr->createWidget(false, screensaverUi); ++ widget->show(); ++ screensaverUi->updatePreview(widget); ++ } else { ++ qInfo() << "screensaverPtr can not be used"; ++ } ++} ++ ++void Screensaver::initIdleTime() ++{ ++ int time = screensaverInterface->property(PREENTRY_TIME).toInt(); ++ screensaverUi->setIdleTime(time); ++} ++ ++void Screensaver::initScreensaver() ++{ ++ QString type = screensaverInterface->property(SCREENSAVER_TYPE).toString(); ++ screensaverUi->setScreensaver(type); ++ initPreview(); ++} ++ ++void Screensaver::initCustomSource() ++{ ++ QString path = screensaverInterface->property(CUSTOM_PATH).toString(); ++ screensaverUi->setSourcePath(path); ++} ++ ++void Screensaver::initSwicthMode() ++{ ++ bool random = screensaverInterface->property(SWITCH_RANDOW).toBool(); ++ screensaverUi->setSwitchRandom(random); ++} ++ ++void Screensaver::initSwitchTime() ++{ ++ int time = screensaverInterface->property(CYCLE_TIME).toInt(); ++ screensaverUi->setSwitchTime(time); ++} ++ ++void Screensaver::initCustomText() ++{ ++ QString text = screensaverInterface->property(CUSTOM_TEXT).toString(); ++ screensaverUi->setCustomText(text); ++} ++ ++void Screensaver::initTextPosition() ++{ ++ bool centered = screensaverInterface->property(CUSTOM_TEXT_CENTERED).toBool(); ++ screensaverUi->setTextCentered(centered); ++} ++ ++void Screensaver::initShowBreakTimeUkui() ++{ ++ bool b = screensaverInterface->property(SHOWTIME_UKUI).toBool(); ++ screensaverUi->setShowUkuiTime(b); ++} ++ ++void Screensaver::initShowBreakTimeCustom() ++{ ++ bool b = screensaverInterface->property(SHOWTIME_CUSTOM).toBool(); ++ screensaverUi->setShowCustomTime(b); ++} ++ ++void Screensaver::initLockscreen() ++{ ++ bool b = screensaverInterface->property(SCREENLOCK_ENABLED).toBool(); ++ screensaverUi->setLockscreen(b); ++} ++ ++void Screensaver::connectUiSignals() ++{ ++ QDBusConnection::sessionBus().connect( ++ "org.ukui.ScreenSaver", ++ "/Screensaver", ++ "org.ukui.ScreenSaver.session.Screensaver", ++ "changed", ++ this, ++ SLOT(dataChanged(QString))); ++ connect(screensaverUi, &ScreensaverUi::idleTimeChanged, this, [=](int time) { ++ toChangeKey = PREENTRY_TIME; ++ screensaverInterface->call("setPreentryTime", time); ++ UkccCommon::buriedSettings(name(), QString("Idle time"), QString("select"), QString::number(time)); ++ }); ++ connect(screensaverUi, &ScreensaverUi::screensaverChanged, this, [=](QString type) { ++ toChangeKey = SCREENSAVER_TYPE; ++ screensaverInterface->call("setScreensaverType", type); ++ UkccCommon::buriedSettings(name(), QString("Screensaver program"), QString("select"), type); ++ }); ++ connect(screensaverUi, &ScreensaverUi::customPathChanged, this, [=](QString path) { ++ toChangeKey = CUSTOM_PATH; ++ screensaverInterface->call("setCustomPath", path); ++ UkccCommon::buriedSettings(name(), QString("Screensaver source Select"), QString("select"), path); ++ }); ++ connect(screensaverUi, &ScreensaverUi::switchRandomChanged, this, [=](bool b) { ++ toChangeKey = SWITCH_RANDOW; ++ screensaverInterface->call("setSwitchRandom", b); ++ UkccCommon::buriedSettings(name(), QString("Random switching"), QString("settings"), b ? "Random" : "Ordinal"); ++ }); ++ connect(screensaverUi, &ScreensaverUi::switchTimeChanged, this, [=](int time) { ++ toChangeKey = CYCLE_TIME; ++ screensaverInterface->call("setCycleTime", time); ++ UkccCommon::buriedSettings(name(), QString("Switching time"), QString("select"), QString::number(time)); ++ }); ++ connect(screensaverUi, &ScreensaverUi::customTextChanged, this, [=](QString text) { ++ toChangeKey = CUSTOM_TEXT; ++ screensaverInterface->call("setCustomText", text); ++ UkccCommon::buriedSettings(name(), QString("Text(up to 30 characters):"), QString("settings"), text); ++ }); ++ connect(screensaverUi, &ScreensaverUi::textCenteredChanged, this, [=](bool b) { ++ toChangeKey = CUSTOM_TEXT_CENTERED; ++ screensaverInterface->call("setCustomTextCentered", b); ++ UkccCommon::buriedSettings( ++ name(), QString("Text position"), QString("settings"), b ? "Centered" : "Randow(Bubble text)"); ++ }); ++ connect(screensaverUi, &ScreensaverUi::showUkuiTimeChanged, this, [=](bool b) { ++ toChangeKey = SHOWTIME_UKUI; ++ screensaverInterface->call("setShowBreakTimeUkui", b); ++ UkccCommon::buriedSettings( ++ name(), QString("custom Show rest time"), QString("settings"), UkccCommon::boolToString(b)); ++ }); ++ connect(screensaverUi, &ScreensaverUi::showCustomChanged, this, [=](bool b) { ++ toChangeKey = SHOWTIME_CUSTOM; ++ screensaverInterface->call("setShowBreakTimeCustom", b); ++ UkccCommon::buriedSettings( ++ name(), QString("ukui Show rest time"), QString("settings"), UkccCommon::boolToString(b)); ++ }); ++ connect(screensaverUi, &ScreensaverUi::lockscreenChanged, this, [=](bool b) { ++ toChangeKey = SCREENLOCK_ENABLED; ++ screensaverInterface->call("setScreenLockEnabled", b); ++ UkccCommon::buriedSettings( ++ name(), QString("Lock screen when screensaver boot"), QString("settings"), UkccCommon::boolToString(b)); ++ }); ++ ++ // 如果在dbus端监听gsetting的改变信号,再发送changed信号,此时再去initPreview可能会异常 ++ // 因为界面端程序此时去读取gsetting的值可能还是修改前的值,该问题应该是qgsetting的设计逻辑问题 ++ // 因此这里去监听gsetting的改变而不是dbus的changed ++ QGSettings *mScreensaverGsettings = nullptr; ++ if (!mScreensaverGsettings) { ++ const QByteArray id("org.ukui.screensaver"); ++ if (QGSettings::isSchemaInstalled(id)) { ++ mScreensaverGsettings = new QGSettings(id, QByteArray(), this); ++ } ++ connect(mScreensaverGsettings, &QGSettings::changed, this, [=](QString key) { ++ if (key == "mode") { ++ initPreview(); ++ } ++ }); ++ } ++} ++ ++void Screensaver::connectToServer() ++{ ++ QThread *NetThread = new QThread; ++ MThread *NetWorker = new MThread; ++ NetWorker->moveToThread(NetThread); ++ connect(NetThread, &QThread::started, NetWorker, &MThread::run); ++ connect(NetWorker, &MThread::keychangedsignal, this, &Screensaver::keyChangedSlot); ++ connect(NetThread, &QThread::finished, NetWorker, &MThread::deleteLater); ++ NetThread->start(); ++} ++ ++void Screensaver::keyChangedSlot(const QString &key) ++{ ++ if (key == "ukui-screensaver") { ++ initContent(); ++ } ++} +diff --git a/src/ukccplugins/screensaver/screensaver.h b/src/ukccplugins/screensaver/screensaver.h +new file mode 100644 +index 0000000..dcf900a +--- /dev/null ++++ b/src/ukccplugins/screensaver/screensaver.h +@@ -0,0 +1,94 @@ ++/* -*- 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 SCREENSAVER_H ++#define SCREENSAVER_H ++ ++#include <QObject> ++#include <QtPlugin> ++#include <QGSettings> ++#include <QtDBus> ++#include "screensaverpluginso.h" ++#include <interface/interface.h> ++#include "screensaverui.h" ++#include <interface/mthread.h> ++#include <interface/ukcccommon.h> ++using namespace ukcc; ++ ++using namespace kdk; ++ ++class Screensaver : public QWidget, CommonInterface ++{ ++ Q_OBJECT ++ Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface") ++ Q_INTERFACES(CommonInterface) ++ ++public: ++ Screensaver(); ++ ~Screensaver(); ++ ++ QString plugini18nName() Q_DECL_OVERRIDE; ++ int pluginTypes() Q_DECL_OVERRIDE; ++ QWidget * pluginUi() Q_DECL_OVERRIDE; ++ const QString name() const Q_DECL_OVERRIDE; ++ void plugin_leave()Q_DECL_OVERRIDE; ++ bool isShowOnHomePage() const Q_DECL_OVERRIDE; ++ QIcon icon() const Q_DECL_OVERRIDE; ++ bool isEnable() const Q_DECL_OVERRIDE; ++ virtual QString translationPath() const { ++ return QStringLiteral("/usr/share/ukui-screensaver/ukccplugins/i18n/%1.ts"); ++ } ++ ++public: ++ void initOptions(); ++ void initContent(); ++ void initPreview(); ++ void initIdleTime(); ++ void initScreensaver(); ++ void initCustomSource(); ++ void initSwicthMode(); ++ void initSwitchTime(); ++ void initCustomText(); ++ void initTextPosition(); ++ void initShowBreakTimeUkui(); ++ void initShowBreakTimeCustom(); ++ void initLockscreen(); ++ void connectUiSignals(); ++ ++private: ++ void preInitialize(); ++ void connectToServer(); ++ ++private Q_SLOTS: ++ void keyChangedSlot(const QString &key); ++ void dataChanged(const QString &key); ++ ++private: ++ QString pluginName; ++ bool mFirstLoad; ++ int pluginType; ++ std::unique_ptr<ScreensaverPlugin> screensaverPtr; ++ ++private: ++ ScreensaverUi *screensaverUi = nullptr; ++ QDBusInterface *screensaverInterface = nullptr; ++ QString toChangeKey; ++}; ++ ++#endif // SCREENSAVER_H +diff --git a/src/ukccplugins/screensaver/screensaverpluginso.h b/src/ukccplugins/screensaver/screensaverpluginso.h +new file mode 100644 +index 0000000..ea22558 +--- /dev/null ++++ b/src/ukccplugins/screensaver/screensaverpluginso.h +@@ -0,0 +1,27 @@ ++#ifndef SCREENSAVERPLUGINSO_H ++#define SCREENSAVERPLUGINSO_H ++ ++#include <QWidget> ++ ++class ScreensaverPlugin ++{ ++public: ++ virtual ~ScreensaverPlugin() {} ++ //插件实例的名称 ++ virtual QString name() const = 0; ++ ++ //创建UI的实例 ++ virtual QWidget* createWidget(bool isScreensaver, QWidget* parent) = 0; ++ ++ //获得插件的展示名称 ++ virtual QString displayName() const = 0; ++}; ++ ++//定义了在QT系统中该接口的全局唯一的ID ++//实现该SDK的插件也要定义相同的ID ++//接口的ID中包含了版本信息,通过该ID我们可以区别不同版本的SDK和插件 ++//Q_DECLARE_INTERFACE宏将类型和ID关联起来,这样QT就可以验证加载的插件是否可以转换成MyPluginInterface类型 ++#define interface_iid "org.ukui.screensaver.screensaver-default1.0.0" ++Q_DECLARE_INTERFACE(ScreensaverPlugin, interface_iid) ++ ++#endif // SCREENSAVERPLUGINSO_H +diff --git a/src/ukccplugins/screensaver/screensaverui.cpp b/src/ukccplugins/screensaver/screensaverui.cpp +new file mode 100644 +index 0000000..3a3df32 +--- /dev/null ++++ b/src/ukccplugins/screensaver/screensaverui.cpp +@@ -0,0 +1,505 @@ ++#include "screensaverui.h" ++#include <QPluginLoader> ++ ++ ++ScreensaverUi::ScreensaverUi() ++{ ++ setAttribute(Qt::WA_DeleteOnClose); ++ uiLayout = new QVBoxLayout(this); ++ uiLayout->setSpacing(8); ++ uiLayout->setMargin(0); ++ initUi(); ++ sendSignals(); ++} ++ ++ScreensaverUi::~ScreensaverUi() ++{ ++ ++} ++ ++void ScreensaverUi::initUi() ++{ ++ initPreview(); ++ initSetting(); ++ uiLayout->addStretch(); ++} ++ ++void ScreensaverUi::initPreview() ++{ ++ screensaverTitle = new KLabel(this); ++ screensaverTitle->setContentsMargins(16, 0, 0, 0); ++ previewFrame = new UkccFrame(this); ++ previewLayout = new QHBoxLayout(previewFrame); ++ previewWidget = new PreviewWidget(this); ++ ++ uiLayout->addWidget(screensaverTitle); ++ uiLayout->addWidget(previewFrame); ++ ++ previewLayout->addWidget(previewWidget); ++ ++ //~ contents_path /Screensaver/Screensaver ++ screensaverTitle->setText(tr("Screensaver")); ++ previewFrame->setFixedHeight(212); ++ previewWidget->setFixedSize(300, 180); ++ previewLayout->addWidget(previewWidget); ++ previewLayout->addStretch(); ++ QHBoxLayout *layout = new QHBoxLayout(previewWidget); ++ layout->setMargin(0); ++} ++ ++void ScreensaverUi::initSetting() ++{ ++ screensaverGroup = new SettingGroup(this); ++ //~ contents_path /Screensaver/Idle time ++ idleTimeWidget = new ComboxWidget(tr("Idle time"), screensaverGroup); ++ //~ contents_path /Screensaver/Screensaver program ++ programWidget = new ComboxWidget(tr("Screensaver program"), screensaverGroup); ++ customizeGroup = new SettingGroup(screensaverGroup); ++ ++ uiLayout->addWidget(screensaverGroup); ++ ++ screensaverGroup->addWidget(idleTimeWidget); ++ screensaverGroup->addWidget(programWidget); ++ screensaverGroup->addWidget(customizeGroup); ++ ++ initSourceFrame(); ++ initSwitchModeFrame(); ++ initSwitchTimeFrame(); ++ initCustomTextFrame(); ++ initTextPositionFrame(); ++ initBreakTimeFrame(); ++ initScreenlockFrame(); ++} ++ ++void ScreensaverUi::initSourceFrame() ++{ ++ UkccFrame *screensaverSourceFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *sourceLayout = new QHBoxLayout(screensaverSourceFrame); ++ KLabel *sourceLabel = new KLabel(); ++ ++ sourcePathLine = new QLineEdit(); ++ sourceButton = new QPushButton(); ++ ++ sourceLayout->setContentsMargins(16, 0, 16, 0); ++ sourceLayout->addWidget(sourceLabel); ++ sourceLayout->addWidget(sourcePathLine); ++ sourceLayout->addWidget(sourceButton); ++ //~ contents_path /Screensaver/Screensaver source ++ sourceLabel->setText(tr("Screensaver source")); ++ sourceLabel->setFixedWidth(220); ++ sourcePathLine->setMinimumWidth(252); ++ sourcePathLine->setReadOnly(true); ++ sourceButton->adjustSize(); ++ sourceButton->setText(tr("Select")); ++ sourceButton->raise(); ++ ++ customizeGroup->addWidget(screensaverSourceFrame); ++} ++ ++void ScreensaverUi::initSwitchModeFrame() ++{ ++ UkccFrame *pictureSwitchFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *randomLayout = new QHBoxLayout(pictureSwitchFrame); ++ KLabel *randomLabel = new KLabel(); ++ QRadioButton *radioOrder = new QRadioButton(); ++ QRadioButton *radioRand = new QRadioButton(); ++ ++ switchModeGroup = new QButtonGroup(); ++ ++ switchModeGroup->addButton(radioOrder, 0); ++ switchModeGroup->addButton(radioRand, 1); ++ ++ radioOrder->setFixedWidth(220); ++ radioRand->adjustSize(); ++ radioOrder->setText(tr("Ordinal")); ++ radioRand->setText(tr("Random")); ++ ++ randomLayout->setContentsMargins(16, 0, 16, 0); ++ randomLayout->addWidget(randomLabel); ++ randomLayout->addWidget(radioOrder); ++ randomLayout->addWidget(radioRand); ++ //~ contents_path /Screensaver/Random switching ++ randomLabel->setText(tr("Random switching")); ++ randomLabel->setFixedWidth(220); ++ randomLayout->addStretch(); ++ ++ customizeGroup->addWidget(pictureSwitchFrame); ++} ++ ++void ScreensaverUi::initSwitchTimeFrame() ++{ ++ UkccFrame *timeSetFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *timeSetLayout = new QHBoxLayout(); ++ KLabel *timeSetLabel = new KLabel(); ++ ++ switchTimeComboBox = new QComboBox(); ++ ++ timeSetFrame->setLayout(timeSetLayout); ++ timeSetLayout->setContentsMargins(16, 0, 16, 0); ++ timeSetLayout->addWidget(timeSetLabel); ++ timeSetLayout->addWidget(switchTimeComboBox); ++ //~ contents_path /Screensaver/Switching time ++ timeSetLabel->setText(tr("Switching time")); ++ timeSetLabel->setFixedWidth(220); ++ switchTimeComboBox->setMinimumWidth(340); ++ ++ customizeGroup->addWidget(timeSetFrame); ++} ++ ++void ScreensaverUi::initCustomTextFrame() ++{ ++ UkccFrame *showTextFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *showTextLayout = new QHBoxLayout(); ++ KLabel *showLabel = new KLabel(); ++ ++ textLineEdit = new QLineEdit(); //用户输入文字 ++ showTextFrame->setLayout(showTextLayout); ++ showTextLayout->setContentsMargins(16, 6, 15, 8); ++ showTextLayout->addWidget(showLabel); ++ showTextLayout->addWidget(textLineEdit); ++ //~ contents_path /Screensaver/Text(up to 30 characters): ++ showLabel->setText(tr("Text(up to 30 characters):")); ++ showLabel->setFixedWidth(220); ++ textLineEdit->setMaxLength(30); ++ ++ customizeGroup->addWidget(showTextFrame); ++} ++ ++void ScreensaverUi::initTextPositionFrame() ++{ ++ UkccFrame *showTextSetFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *textSetLayout = new QHBoxLayout(showTextSetFrame); ++ KLabel *textSetLabel = new KLabel(); ++ QRadioButton *radioRandom = new QRadioButton(this); ++ QRadioButton *radioCenter = new QRadioButton(this); ++ ++ textPositionGroup = new QButtonGroup(); ++ textPositionGroup->addButton(radioRandom, 0); ++ textPositionGroup->addButton(radioCenter, 1); ++ ++ showTextSetFrame->setFixedHeight(60); ++ textSetLayout->addWidget(textSetLabel); ++ textSetLayout->setContentsMargins(16,0,16,0); ++ //~ contents_path /Screensaver/Text position ++ textSetLabel->setText(tr("Text position")); ++ textSetLabel->setFixedWidth(220); ++ radioRandom->setFixedWidth(220); ++ radioCenter->adjustSize(); ++ ++ textSetLayout->addWidget(radioRandom); ++ textSetLayout->addWidget(radioCenter); ++ textSetLayout->addStretch(); ++ radioCenter->setText(tr("Centered")); ++ radioRandom->setText(tr("Randow(Bubble text)")); ++ ++ customizeGroup->addWidget(showTextSetFrame); ++} ++ ++void ScreensaverUi::initBreakTimeFrame() ++{ ++ UkccFrame *showTimeFrame = new UkccFrame(screensaverGroup, UkccFrame::BorderRadiusStyle::Around, true); ++ QHBoxLayout *showTimeLayout = new QHBoxLayout(showTimeFrame); ++ KLabel *showTimeLabel = new KLabel(); ++ ++ showTimeLayout->setContentsMargins(16,0,16,0); ++ showTimeLayout->addWidget(showTimeLabel); ++ //添加休息时间显示按钮 ++ showCustomTimeBtn = new KSwitchButton(showTimeFrame); ++ showUkuiTimeBtn = new KSwitchButton(showTimeFrame); ++ showTimeLayout->addStretch(); ++ showTimeLayout->addWidget(showCustomTimeBtn); ++ showTimeLayout->addWidget(showUkuiTimeBtn); ++ showTimeLabel->setFixedWidth(220); ++ ++ //~ contents_path /Screensaver/Show rest time ++ showTimeLabel->setText(tr("Show rest time")); ++ screensaverGroup->addWidget(showTimeFrame); ++} ++ ++void ScreensaverUi::initScreenlockFrame() ++{ ++ UkccFrame *lockFrame = new UkccFrame(screensaverGroup, UkccFrame::BorderRadiusStyle::Around, true);; ++ QHBoxLayout *lockLayout = new QHBoxLayout(lockFrame); ++ ++ //~ contents_path /Screensaver/Lock screen when screensaver boot ++ KLabel *lockLabel = new KLabel(); ++ lockLabel->setText(tr("Lock screen when screensaver boot")); ++ lockLabel->setFixedWidth(400); ++ ++ lockFrame->setFixedHeight(60); ++ lockLayout->setContentsMargins(16,0,16,0); ++ lockLayout->addWidget(lockLabel); ++ ++ lockButton = new KSwitchButton(lockFrame); ++ lockLayout->addStretch(); ++ lockLayout->addWidget(lockButton); ++ ++ screensaverGroup->addWidget(lockFrame); ++} ++ ++void ScreensaverUi::setIdleTimeOptions(const QStringList &textList, const QList<int> &dataList) ++{ ++ if (textList.size() == dataList.size()) { ++ idleTimeWidget->comboBox()->clear(); ++ for (int i = 0; i < textList.size(); ++i) { ++ idleTimeWidget->comboBox()->addItem(textList.at(i), dataList.at(i)); ++ } ++ } ++} ++ ++void ScreensaverUi::setScreensaverOptions(const QStringList &textList, const QStringList &dataList) ++{ ++ if (textList.size() == dataList.size()) { ++ programWidget->comboBox()->clear(); ++ for (int i = 0; i < textList.size(); ++i) { ++ programWidget->comboBox()->addItem(textList.at(i), dataList.at(i)); ++ } ++ } ++} ++ ++void ScreensaverUi::setSwitchTimeOptions(const QStringList &textList, const QList<int> &dataList) ++{ ++ if (textList.size() == dataList.size()) { ++ switchTimeComboBox->clear(); ++ for (int i = 0; i < textList.size(); ++i) { ++ switchTimeComboBox->addItem(textList.at(i), dataList.at(i)); ++ } ++ } ++} ++ ++void ScreensaverUi::setIdleTime(int time) ++{ ++ for (int i = 0; i < idleTimeWidget->comboBox()->count(); ++i) { ++ if (time == idleTimeWidget->comboBox()->itemData(i)) { ++ idleTimeWidget->comboBox()->blockSignals(true); ++ idleTimeWidget->comboBox()->setCurrentIndex(i); ++ idleTimeWidget->comboBox()->blockSignals(false); ++ } ++ } ++} ++ ++void ScreensaverUi::setScreensaver(QString type) ++{ ++ for (int i = 0; i < programWidget->comboBox()->count(); ++i) { ++ if (type == programWidget->comboBox()->itemData(i)) { ++ programWidget->comboBox()->blockSignals(true); ++ programWidget->comboBox()->setCurrentIndex(i); ++ programWidget->comboBox()->blockSignals(false); ++ } ++ } ++ ++ if (type == "ukui") { ++ customizeGroup->setVisible(false); ++ showUkuiTimeBtn->setVisible(true); ++ showCustomTimeBtn->setVisible(false); ++ } else if (type == "custom") { ++ customizeGroup->setVisible(true); ++ showUkuiTimeBtn->setVisible(false); ++ showCustomTimeBtn->setVisible(true); ++ } ++} ++ ++void ScreensaverUi::updatePreview(QWidget *w) ++{ ++ for (QObject *o : previewWidget->children()) { ++ if (o->objectName() == "screensaverWidget") { ++ delete o; ++ o = nullptr; ++ } ++ } ++ w->setObjectName("screensaverWidget"); ++ previewWidget->layout()->addWidget(w); ++ previewWidget->update(); ++} ++ ++void ScreensaverUi::setSourcePath(const QString &text) ++{ ++ if (sourcePathLine == nullptr) { ++ return; ++ } ++ ++ QFontMetrics fontMetrics(sourcePathLine->font()); ++ int fontSize = fontMetrics.width(text); ++ if (fontSize > sourcePathLine->width()) { ++ sourcePathLine->setText(fontMetrics.elidedText(text, Qt::ElideRight, sourcePathLine->width())); ++ sourcePathLine->setToolTip(text); ++ } else { ++ sourcePathLine->setText(text); ++ sourcePathLine->setToolTip(""); ++ } ++} ++ ++void ScreensaverUi::setSwitchRandom(const bool &b) ++{ ++ switchModeGroup->blockSignals(true); ++ if (b) { ++ switchModeGroup->button(1)->setChecked(true); ++ } else { ++ switchModeGroup->button(0)->setChecked(true); ++ } ++ switchModeGroup->blockSignals(false); ++} ++ ++void ScreensaverUi::setSwitchTime(const int &time) ++{ ++ for (int i = 0; i < switchTimeComboBox->count(); ++i) { ++ if (time == switchTimeComboBox->itemData(i)) { ++ switchTimeComboBox->blockSignals(true); ++ switchTimeComboBox->setCurrentIndex(i); ++ switchTimeComboBox->blockSignals(false); ++ } ++ } ++} ++ ++void ScreensaverUi::setCustomText(const QString &text) ++{ ++ textLineEdit->blockSignals(true); ++ textLineEdit->setText(text); ++ textLineEdit->blockSignals(false); ++} ++ ++void ScreensaverUi::setTextCentered(const bool &b) ++{ ++ textPositionGroup->blockSignals(true); ++ if (b) { ++ textPositionGroup->button(1)->setChecked(true); ++ } else { ++ textPositionGroup->button(0)->setChecked(true); ++ } ++ textPositionGroup->blockSignals(false); ++} ++ ++void ScreensaverUi::setShowUkuiTime(const bool &b) ++{ ++ showUkuiTimeBtn->blockSignals(true); ++ showUkuiTimeBtn->setChecked(b); ++ showUkuiTimeBtn->blockSignals(false); ++} ++ ++void ScreensaverUi::setShowCustomTime(const bool &b) ++{ ++ showCustomTimeBtn->blockSignals(true); ++ showCustomTimeBtn->setChecked(b); ++ showCustomTimeBtn->blockSignals(false); ++} ++ ++void ScreensaverUi::setLockscreen(const bool &b) ++{ ++ lockButton->blockSignals(true); ++ lockButton->setChecked(b); ++ lockButton->blockSignals(false); ++} ++ ++void ScreensaverUi::sendSignals() ++{ ++ connect(idleTimeWidget->comboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) { ++ Q_UNUSED(index) ++ Q_EMIT idleTimeChanged(idleTimeWidget->comboBox()->currentData().toInt()); ++ }); ++ connect(programWidget->comboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) { ++ Q_UNUSED(index) ++ QString type = programWidget->comboBox()->currentData().toString(); ++ Q_EMIT screensaverChanged(type); ++ if (type == "ukui") { ++ customizeGroup->setVisible(false); ++ showUkuiTimeBtn->setVisible(true); ++ showCustomTimeBtn->setVisible(false); ++ } else if (type == "custom") { ++ customizeGroup->setVisible(true); ++ showUkuiTimeBtn->setVisible(false); ++ showCustomTimeBtn->setVisible(true); ++ } ++ }); ++ connect(sourceButton, &QPushButton::clicked, this, [=]() { ++ QString filter; ++ filter = tr("Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)"); ++ QFileDialog fd(this); ++ ++ QList<QUrl> 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<QUrl> 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(sourcePathLine->text())); ++ fd.setAcceptMode(QFileDialog::AcceptOpen); ++ fd.setViewMode(QFileDialog::List); ++ fd.setNameFilter(filter); ++ fd.setFileMode(QFileDialog::Directory); ++ fd.setWindowTitle(tr("select custom screensaver dir")); ++ 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")); ++ ++ fd.setSidebarUrls(usb_list + mntUrlList); ++ ++ if (fd.exec() != QDialog::Accepted) { ++ return; ++ } ++ QString selectedfile; ++ selectedfile = fd.selectedFiles().first(); ++ if(selectedfile != "") { //非点击【取消】时 ++ setSourcePath(selectedfile); ++ Q_EMIT customPathChanged(selectedfile); ++ } ++ }); ++ connect(switchModeGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, [=](int id) { ++ if (id == 0) { ++ Q_EMIT switchRandomChanged(false); ++ } else { ++ Q_EMIT switchRandomChanged(true); ++ } ++ }); ++ connect(switchTimeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) { ++ Q_UNUSED(index) ++ Q_EMIT switchTimeChanged(switchTimeComboBox->currentData().toInt()); ++ }); ++ connect(textLineEdit, &QLineEdit::textChanged, this, [=](){ ++ Q_EMIT customTextChanged(textLineEdit->text()); ++ }); ++ connect(textPositionGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, [=](int id) { ++ if (id == 0) { ++ Q_EMIT textCenteredChanged(false); ++ } else { ++ Q_EMIT textCenteredChanged(true); ++ } ++ }); ++ connect(showUkuiTimeBtn, &KSwitchButton::stateChanged, this, [=]() { ++ Q_EMIT showUkuiTimeChanged(showUkuiTimeBtn->isChecked()); ++ }); ++ connect(showCustomTimeBtn, &KSwitchButton::stateChanged, this, [=]() { ++ Q_EMIT showCustomChanged(showCustomTimeBtn->isChecked()); ++ }); ++ connect(lockButton, &KSwitchButton::stateChanged, this, [=]() { ++ Q_EMIT lockscreenChanged(lockButton->isChecked()); ++ }); ++} +diff --git a/src/ukccplugins/screensaver/screensaverui.h b/src/ukccplugins/screensaver/screensaverui.h +new file mode 100644 +index 0000000..92d67ec +--- /dev/null ++++ b/src/ukccplugins/screensaver/screensaverui.h +@@ -0,0 +1,94 @@ ++#ifndef SCREENSAVERUI_H ++#define SCREENSAVERUI_H ++ ++#include <widgets/settinggroup.h> ++#include <widgets/switchwidget.h> ++#include <widgets/pushbuttonwidget.h> ++#include <widgets/comboxwidget.h> ++#include "screensaverpluginso.h" ++#include "previewwidget.h" ++#include <QHBoxLayout> ++#include <QWidget> ++#include <QRadioButton> ++#include <QLineEdit> ++#include <QFileDialog> ++#include <QButtonGroup> ++#include <QFileSystemWatcher> ++#include <kysdk/applications/klabel.h> ++ ++using namespace kdk; ++ ++class ScreensaverUi : public QWidget ++{ ++ Q_OBJECT ++public: ++ ScreensaverUi(); ++ ~ScreensaverUi(); ++ void setIdleTimeOptions(const QStringList &textList, const QList<int> &dataList); ++ void setScreensaverOptions(const QStringList &textList, const QStringList &dataList); ++ void setSwitchTimeOptions(const QStringList &textList, const QList<int> &dataList); ++ void updatePreview(QWidget *w); ++ void setSourcePath(const QString &text); ++ void setSwitchRandom(const bool &b); ++ void setSwitchTime(const int &time); ++ void setCustomText(const QString &text); ++ void setTextCentered(const bool &b); ++ void setShowUkuiTime(const bool &b); ++ void setShowCustomTime(const bool &b); ++ void setLockscreen(const bool &b); ++ ++public: ++ void setIdleTime(int time); ++ void setScreensaver(QString type); ++ ++private: ++ void initUi(); ++ void initPreview(); ++ void initSetting(); ++ void initSourceFrame(); ++ void initSwitchModeFrame(); ++ void initSwitchTimeFrame(); ++ void initCustomTextFrame(); ++ void initTextPositionFrame(); ++ void initBreakTimeFrame(); ++ void initScreenlockFrame(); ++ void sendSignals(); ++ ++private: ++ QVBoxLayout *uiLayout = nullptr; ++ ++private: ++ KLabel *screensaverTitle = nullptr; ++ UkccFrame *previewFrame = nullptr; ++ QHBoxLayout *previewLayout = nullptr; ++ PreviewWidget *previewWidget = nullptr; ++ SettingGroup *screensaverGroup = nullptr; ++ ComboxWidget *idleTimeWidget = nullptr; ++ ComboxWidget *programWidget = nullptr; ++ SettingGroup *customizeGroup = nullptr; ++ ++private: ++ QLineEdit *sourcePathLine = nullptr; ++ QPushButton *sourceButton = nullptr; ++ QButtonGroup *switchModeGroup = nullptr; ++ QComboBox *switchTimeComboBox = nullptr; ++ QLineEdit *textLineEdit = nullptr; ++ QButtonGroup *textPositionGroup = nullptr; ++ KSwitchButton *showCustomTimeBtn = nullptr; ++ KSwitchButton *showUkuiTimeBtn = nullptr; ++ KSwitchButton *lockButton = nullptr; ++ ++Q_SIGNALS: ++ void idleTimeChanged(int time); ++ void screensaverChanged(QString type); ++ void customPathChanged(QString path); ++ void switchRandomChanged(bool b); ++ void switchTimeChanged(int time); ++ void customTextChanged(QString text); ++ void textCenteredChanged(bool b); ++ void showUkuiTimeChanged(bool b); ++ void showCustomChanged(bool b); ++ void lockscreenChanged(bool b); ++}; ++ ++#endif // SCREENSAVERUI_H +diff --git a/src/ukccplugins/sessiondbus/screenlockinterface.cpp b/src/ukccplugins/sessiondbus/screenlockinterface.cpp +new file mode 100644 +index 0000000..f14ae59 +--- /dev/null ++++ b/src/ukccplugins/sessiondbus/screenlockinterface.cpp +@@ -0,0 +1,153 @@ ++/* ++ * Copyright (C) 2025 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, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see <http://www.gnu.org/licenses/>. ++ * ++ **/ ++#include "screenlockinterface.h" ++#include <sys/stat.h> ++#include "../../lock-backend/gsettingshelper.h" ++ ++ScreenlockInterface::ScreenlockInterface(DbusUpperInterface *upperInterface, QObject *parent) ++ : QObject(parent), m_upperInterface(upperInterface) ++{ ++} ++ ++bool ScreenlockInterface::initData() ++{ ++ if (!m_isInited) { ++ mUKCConfig = QDir::homePath() + "/.config/ukui/ukui-control-center.conf"; ++ lockSetting = new QSettings(mUKCConfig, QSettings::IniFormat, this); ++ m_isInited = true; ++ } ++ return m_isInited; ++} ++ ++ScreenlockInterface::~ScreenlockInterface() {} ++ ++void ScreenlockInterface::setShowOnLogin(bool b) ++{ ++ initData(); ++ QString bgStr; ++ struct stat fileStat; ++ if (b && m_upperInterface) { ++ bgStr = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_BACKGROUND).toString(); ++ stat(bgStr.toStdString().c_str(), &fileStat); ++ if (fileStat.st_uid != 0) { // 在普通用户下 ++ bgStr = copyLoginFile(bgStr); ++ } ++ } else if (!b) { ++ bgStr = ""; ++ } ++ lockSetting->beginGroup("ScreenLock"); ++ lockSetting->setValue("lockStatus", b); ++ lockSetting->endGroup(); ++ ++ QString name = qgetenv("USER"); ++ if (name.isEmpty()) { ++ name = qgetenv("USERNAME"); ++ } ++ ++ QString lockfilename = "/var/lib/lightdm-data/" + name + "/ukui-greeter.conf"; ++ QSettings lockLoginSettings(lockfilename, QSettings::IniFormat, this); ++ ++ lockLoginSettings.beginGroup("greeter"); ++ lockLoginSettings.setValue("backgroundPath", bgStr); ++ lockLoginSettings.endGroup(); ++ Q_EMIT changed("showOnLogin"); ++} ++ ++void ScreenlockInterface::setWallpaper(QString f) ++{ ++ initData(); ++ if (m_upperInterface) { ++ m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_BACKGROUND, f); ++ } ++ setShowOnLogin(getShowOnLogin()); ++ Q_EMIT changed("wallpaper"); ++} ++ ++bool ScreenlockInterface::getShowOnLogin() ++{ ++ initData(); ++ if (!QFile::exists(mUKCConfig)) { ++ setShowOnLogin(true); ++ } ++ ++ lockSetting->beginGroup("ScreenLock"); ++ lockSetting->sync(); ++ bool status = lockSetting->value("lockStatus").toBool(); ++ lockSetting->endGroup(); ++ return status; ++} ++ ++QString ScreenlockInterface::getWallpaper() ++{ ++ initData(); ++ QString initBgStr = ""; ++ if (m_upperInterface) { ++ initBgStr = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_BACKGROUND).toString(); ++ } ++ ++ // 锁屏壁纸不存在,则展示默认壁纸 ++ if (!QFile::exists(initBgStr)) { ++ initBgStr = "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; ++ if (!QFile::exists(initBgStr)) { ++ initBgStr = "/usr/share/backgrounds/1-openkylin.jpg"; ++ } ++ } ++ return initBgStr; ++} ++ ++QStringList ScreenlockInterface::getPreviewWallpapers() ++{ ++ initData(); ++ QDBusInterface interface( ++ "org.ukui.ukcc.session", "/Wallpaper", "org.ukui.ukcc.session.Wallpaper", QDBusConnection::sessionBus(), this); ++ if (interface.isValid()) { ++ return interface.property("previewWallpapers").toStringList(); ++ } ++ return QStringList(); ++} ++ ++QStringList ScreenlockInterface::getSourceWallpapers() ++{ ++ QDBusInterface interface( ++ "org.ukui.ukcc.session", "/Wallpaper", "org.ukui.ukcc.session.Wallpaper", QDBusConnection::sessionBus(), this); ++ if (interface.isValid()) { ++ return interface.property("sourceWallpapers").toStringList(); ++ } ++ return QStringList(); ++} ++ ++void ScreenlockInterface::resetDefault() ++{ ++ initData(); ++ if (m_upperInterface) { ++ QString strDefBg = m_upperInterface->getGSettingsInstance()->ResetLockScreenConf(KEY_BACKGROUND).toString(); ++ setWallpaper(strDefBg); ++ } ++} ++ ++QString ScreenlockInterface::copyLoginFile(QString fileName) ++{ ++ QString name = qgetenv("USER"); ++ if (name.isEmpty()) { ++ name = qgetenv("USERNAME"); ++ } ++ QString loginFilename = "/var/lib/lightdm-data/" + name + "/" + "loginBackground"; ++ QString loginCmd = QString("cp '%1' %2").arg(fileName).arg(loginFilename); ++ system(loginCmd.toUtf8().data()); ++ return loginFilename; ++} +diff --git a/src/ukccplugins/sessiondbus/screenlockinterface.h b/src/ukccplugins/sessiondbus/screenlockinterface.h +new file mode 100644 +index 0000000..8458a46 +--- /dev/null ++++ b/src/ukccplugins/sessiondbus/screenlockinterface.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (C) 2025 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, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see <http://www.gnu.org/licenses/>. ++ * ++ **/ ++#ifndef SCREENLOCKINTERFACE_H ++#define SCREENLOCKINTERFACE_H ++ ++#include <QObject> ++#include <QtDBus> ++#include "../../lock-backend/dbusupperinterface.h" ++ ++class ScreenlockInterface : public QObject ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.ScreenSaver.session.Screenlock") ++ Q_PROPERTY(bool showOnLogin READ getShowOnLogin) ++ Q_PROPERTY(QString wallpaper READ getWallpaper) ++ Q_PROPERTY(QStringList previewWallpapers READ getPreviewWallpapers) ++ Q_PROPERTY(QStringList sourceWallpapers READ getSourceWallpapers) ++ ++public: ++ ScreenlockInterface(DbusUpperInterface *upperInterface, QObject *parent = nullptr); ++ ~ScreenlockInterface(); ++ bool getShowOnLogin(); ++ QString getWallpaper(); ++ QStringList getPreviewWallpapers(); ++ QStringList getSourceWallpapers(); ++ ++public Q_SLOTS: ++ void setShowOnLogin(bool b); ++ void setWallpaper(QString f); ++ void resetDefault(); ++ ++private: ++ QString copyLoginFile(QString fileName); ++ bool initData(); ++ ++private: ++ QStringList previewWallpaperList; ++ QStringList sourceWallpaperList; ++ QString mUKCConfig = ""; ++ QSettings *lockSetting = nullptr; ++ DbusUpperInterface *m_upperInterface = nullptr; ++ bool m_isInited = false; ++ ++Q_SIGNALS: ++ void changed(QString key); ++}; ++ ++#endif // SCREENLOCKINTERFACE_H +diff --git a/src/ukccplugins/sessiondbus/screensaverinterface.cpp b/src/ukccplugins/sessiondbus/screensaverinterface.cpp +new file mode 100644 +index 0000000..1a8e884 +--- /dev/null ++++ b/src/ukccplugins/sessiondbus/screensaverinterface.cpp +@@ -0,0 +1,193 @@ ++/* ++ * Copyright (C) 2025 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, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see <http://www.gnu.org/licenses/>. ++ * ++ **/ ++#include "screensaverinterface.h" ++#include "../../lock-backend/gsettingshelper.h" ++ ++ScreensaverInterface::ScreensaverInterface(DbusUpperInterface *upperInterface, QObject *parent) ++ : QObject(parent), m_upperInterface(upperInterface) ++{ ++} ++ ++bool ScreensaverInterface::initData() ++{ ++ if (!m_isInited) { ++ mScreensaverType.clear(); ++ QString mode = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_MODE).toString(); ++ if (mode == "default-ukui") { ++ mScreensaverType = "ukui"; ++ } else if (mode == "default-ukui-custom") { ++ mScreensaverType = "custom"; ++ } else { ++ mScreensaverType = "other"; ++ } ++ connect( ++ m_upperInterface->getGSettingsInstance().get(), ++ &GSettingsHelper::lockScreenConfigChanged, ++ this, ++ [=](QString strKey, QVariant value) { ++ if (strKey == KEY_MODE) { ++ QString mode = value.toString(); ++ if (mode == "default-ukui") { ++ mScreensaverType = "ukui"; ++ } else if (mode == "default-ukui-custom") { ++ mScreensaverType = "custom"; ++ } else { ++ mScreensaverType = "other"; ++ } ++ } ++ }); ++ m_isInited = true; ++ } ++ return m_isInited; ++} ++ ++ScreensaverInterface::~ScreensaverInterface() {} ++ ++int ScreensaverInterface::getPreentryTime() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_IDLE_DELAY).toInt(); ++} ++ ++void ScreensaverInterface::setPreentryTime(int time) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_IDLE_DELAY, time); ++ Q_EMIT changed("preentryTime"); ++} ++ ++QString ScreensaverInterface::getScreensaverType() ++{ ++ initData(); ++ return mScreensaverType; ++} ++ ++void ScreensaverInterface::setScreensaverType(QString type) ++{ ++ initData(); ++ if (type == "ukui") { ++ m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_MODE, "default-ukui"); ++ } else if (type == "custom") { ++ m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_MODE, "default-ukui-custom"); ++ } ++ Q_EMIT changed("screensaverType"); ++} ++ ++bool ScreensaverInterface::getShowBreakTimeUkui() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME).toBool(); ++} ++ ++void ScreensaverInterface::setShowBreakTimeUkui(bool b) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME, b); ++ Q_EMIT changed("showBreakTimeUkui"); ++} ++ ++bool ScreensaverInterface::getShowBreakTimeCustom() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME).toBool(); ++} ++ ++void ScreensaverInterface::setShowBreakTimeCustom(bool b) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME, b); ++ Q_EMIT changed("showBreakTimeCustom"); ++} ++ ++bool ScreensaverInterface::getScreenLockEnabled() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_LOCK_ENABLED).toBool(); ++} ++ ++void ScreensaverInterface::setScreenLockEnabled(bool b) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_LOCK_ENABLED, b); ++ Q_EMIT changed("screenLockEnabled"); ++} ++ ++QString ScreensaverInterface::getcustomPath() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_BACKGROUND_PATH).toString(); ++} ++ ++void ScreensaverInterface::setCustomPath(QString path) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_BACKGROUND_PATH, path); ++ Q_EMIT changed("customPath"); ++} ++ ++bool ScreensaverInterface::getSwitchRandom() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool(); ++} ++ ++void ScreensaverInterface::setSwitchRandom(bool b) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, b); ++ Q_EMIT changed("switchRandom"); ++} ++ ++int ScreensaverInterface::getCycleTime() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_CYCLE_TIME).toInt(); ++} ++ ++void ScreensaverInterface::setCycleTime(int time) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_CYCLE_TIME, time); ++ Q_EMIT changed("cycleTime"); ++} ++ ++QString ScreensaverInterface::getCustomText() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_MYTEXT).toString(); ++} ++ ++void ScreensaverInterface::setCustomText(QString text) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_MYTEXT, text); ++ Q_EMIT changed("customText"); ++} ++ ++bool ScreensaverInterface::getCustomTextCentered() ++{ ++ initData(); ++ return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_TEXT_IS_CENTER).toBool(); ++} ++ ++void ScreensaverInterface::setCustomTextCentered(bool b) ++{ ++ initData(); ++ m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_TEXT_IS_CENTER, b); ++ Q_EMIT changed("customTextCentered"); ++} +diff --git a/src/ukccplugins/sessiondbus/screensaverinterface.h b/src/ukccplugins/sessiondbus/screensaverinterface.h +new file mode 100644 +index 0000000..654a6db +--- /dev/null ++++ b/src/ukccplugins/sessiondbus/screensaverinterface.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2025 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, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see <http://www.gnu.org/licenses/>. ++ * ++ **/ ++#ifndef SCREENSAVERINTERFACE_H ++#define SCREENSAVERINTERFACE_H ++ ++#include <QObject> ++#include <QtDBus> ++#include "../../lock-backend/dbusupperinterface.h" ++ ++class ScreensaverInterface : public QObject ++{ ++ Q_OBJECT ++ Q_CLASSINFO("D-Bus Interface", "org.ukui.ScreenSaver.session.Screensaver") ++ Q_PROPERTY(int preentryTime READ getPreentryTime) ++ Q_PROPERTY(QString screensaverType READ getScreensaverType) ++ Q_PROPERTY(bool showBreakTimeUkui READ getShowBreakTimeUkui) ++ Q_PROPERTY(bool showBreakTimeCustom READ getShowBreakTimeCustom) ++ Q_PROPERTY(bool screenLockEnabled READ getScreenLockEnabled) ++ Q_PROPERTY(QString customPath READ getcustomPath) ++ Q_PROPERTY(bool switchRandom READ getSwitchRandom) ++ Q_PROPERTY(int cycleTime READ getCycleTime) ++ Q_PROPERTY(QString customText READ getCustomText) ++ Q_PROPERTY(bool customTextCentered READ getCustomTextCentered) ++ ++public: ++ ScreensaverInterface(DbusUpperInterface *upperInterface, QObject *parent = nullptr); ++ ~ScreensaverInterface(); ++ int getPreentryTime(); ++ QString getScreensaverType(); ++ bool getShowBreakTimeUkui(); ++ bool getShowBreakTimeCustom(); ++ bool getScreenLockEnabled(); ++ QString getcustomPath(); ++ bool getSwitchRandom(); ++ int getCycleTime(); ++ QString getCustomText(); ++ bool getCustomTextCentered(); ++ ++private: ++ bool initData(); ++ ++private: ++ QString mScreensaverType; ++ DbusUpperInterface *m_upperInterface = nullptr; ++ bool m_isInited = false; ++ ++public Q_SLOTS: ++ void setPreentryTime(int time); ++ void setScreensaverType(QString type); ++ void setShowBreakTimeUkui(bool b); ++ void setShowBreakTimeCustom(bool b); ++ void setScreenLockEnabled(bool b); ++ void setCustomPath(QString path); ++ void setSwitchRandom(bool b); ++ void setCycleTime(int time); ++ void setCustomText(QString Text); ++ void setCustomTextCentered(bool b); ++ ++Q_SIGNALS: ++ void changed(QString key); ++}; ++ ++#endif // SCREENSAVERINTERFACE_H +diff --git a/src/userinfo.cpp b/src/userinfo.cpp +index 7808f3a..c9e03a8 100644 +--- a/src/userinfo.cpp ++++ b/src/userinfo.cpp +@@ -16,8 +16,8 @@ + * + **/ + #include "userinfo.h" +-#include "global_utils.h" +-#include "definetypes.h" ++#include "common/global_utils.h" ++#include "common/definetypes.h" + #include <QDBusConnection> + #include <QDBusMessage> + #include <QDBusInterface> +diff --git a/src/widgets/authdialog.cpp b/src/widgets/authdialog.cpp +index 62c9b77..c20f7f0 100644 +--- a/src/widgets/authdialog.cpp ++++ b/src/widgets/authdialog.cpp +@@ -35,6 +35,7 @@ + #include <unistd.h> + #include <sys/types.h> + #include <pwd.h> ++#include <syslog.h> + #include "../lock-dialog/pam-tally.h" + #include "global_utils.h" + #include "securityquestionanswer.h" +@@ -57,11 +58,13 @@ AuthDialog::AuthDialog(LockDialogModel *model, UserInfoPtr userInfo, QWidget *pa + , m_curUserInfo(userInfo) + , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this)) + { ++ pam_tally_init(); + initUI(); + } + + void AuthDialog::initUI() + { ++ installEventFilter(this); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setAlignment(Qt::AlignCenter); + mainLayout->setSpacing(WIDGET_HEIGHT_SPACING); +@@ -147,6 +150,8 @@ bool AuthDialog::eventFilter(QObject *obj, QEvent *event) + } else { + Q_EMIT bottomPositionChanged(mapToParent(m_widgetLoginOpts->geometry().topLeft()).y()); + } ++ } else if (this == obj && event->type() == QEvent::Show) { ++ pam_tally_init(); + } + } + +@@ -875,8 +880,8 @@ void AuthDialog::onPamShowMessage(QString strMsg, int nType) + void AuthDialog::showPwdTipBtn() + { + m_pPwdTipMessage->setVisible(m_userFailedTimesMap[m_curUserInfo->uid()] >= 1); +- if (m_userFailedTimesMap[m_curUserInfo->uid()] >= 1 && +- m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid()) != "") { ++ if (m_userFailedTimesMap[m_curUserInfo->uid()] >= 1 ++ && m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid()) != "") { + m_pEditLayout->setContentsMargins(48, 0, 0, 0); + m_pPwdTipMessage->show(); + m_pPwdTipMessage->setToolTip(m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid())); +@@ -984,10 +989,13 @@ void AuthDialog::onPamShowPrompt(QString strPrompt, int nType) + // }); + // isPowerup = false; + // } else { ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] check bio auth begin!!"); + performBiometricAuth(); ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] check bio auth done!!"); + // } + } + } else { ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] auth alraedy!!"); + m_isNameLogin = false; + qDebug() << "m_isNameLogin = false"; + m_passwordEdit->stopWaiting(); +@@ -1127,13 +1135,16 @@ void AuthDialog::onPamAuthCompleted() + startAuth(); + if (++m_userFailedTimesMap[m_curUserInfo->uid()] >= 1) { + qDebug() << "m_authFailedTimes = " << m_userFailedTimesMap[m_curUserInfo->uid()]; +- showPwdTipBtn(); ++ showPwdTipBtn(); + Q_EMIT showResetPasswdBtn(); + } + } else { + showAuthenticated(false); + } + } ++ if (!m_isInhibitShow) { ++ show(); ++ } + } + + void AuthDialog::onRespond(const QString &strRes) +@@ -1174,28 +1185,25 @@ void AuthDialog::onRespond(const QString &strRes) + + void AuthDialog::startAuth() + { ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] auth start!!"); + if (!m_curUserInfo->name().isEmpty()) { +- qint64 lnDiffTime = qAbs(m_lastPamAuthTime.msecsTo(QDateTime::currentDateTime())); +- if (lnDiffTime >= 1000 || m_strLastPamAuthName != m_curUserInfo->name()) { +- m_lastPamAuthTime = QDateTime::currentDateTime(); +- m_bRecvPrompt = false; +- m_bHasUnacknowledgedMsg = false; +- // 用户认证 +- if (m_curUserInfo->name() == "*guest") { // 游客登录 +- qDebug() << "guest login"; +- m_passwordEdit->show(); +- m_passwordEdit->setPrompt(tr("login")); +- m_strLastPamAuthName = "*guest"; +- } else if (m_curUserInfo->name() == "*login") { // 手动输入用户名 +- Q_EMIT m_modelLockDialog->pamAuthenticate(""); +- m_strLastPamAuthName = "*login"; +- } else { +- qDebug() << "login: " << m_curUserInfo->name(); +- Q_EMIT m_modelLockDialog->pamAuthenticate(m_curUserInfo->name()); +- m_passwordEdit->clear(); +- m_passwordEdit->readOnly(true); +- m_strLastPamAuthName = m_curUserInfo->name(); +- } ++ m_bRecvPrompt = false; ++ m_bHasUnacknowledgedMsg = false; ++ // 用户认证 ++ if (m_curUserInfo->name() == "*guest") { // 游客登录 ++ qDebug() << "guest login"; ++ m_passwordEdit->show(); ++ m_passwordEdit->setPrompt(tr("login")); ++ m_strLastPamAuthName = "*guest"; ++ } else if (m_curUserInfo->name() == "*login") { // 手动输入用户名 ++ Q_EMIT m_modelLockDialog->pamAuthenticate(""); ++ m_strLastPamAuthName = "*login"; ++ } else { ++ qDebug() << "login: " << m_curUserInfo->name(); ++ Q_EMIT m_modelLockDialog->pamAuthenticate(m_curUserInfo->name()); ++ m_passwordEdit->clear(); ++ m_passwordEdit->readOnly(true); ++ m_strLastPamAuthName = m_curUserInfo->name(); + } + } + } +diff --git a/src/widgets/fullbackgroundwidget.cpp b/src/widgets/fullbackgroundwidget.cpp +index b59017a..463e305 100644 +--- a/src/widgets/fullbackgroundwidget.cpp ++++ b/src/widgets/fullbackgroundwidget.cpp +@@ -55,8 +55,8 @@ using namespace kdk; + #include <kysec/status.h> + #endif + +-FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, QWidget *parent) +- : QWidget(parent), m_modelLockDialog(model) ++FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, bool isStartup, QWidget *parent) ++ : QWidget(parent), m_modelLockDialog(model), m_isStartupMode(isStartup) + { + initCurrentBackground(); + initUI(); +@@ -114,8 +114,7 @@ void FullBackgroundWidget::initUI() + moveToPrimaryScreen(); + } + +- if (m_modelLockDialog->getAgreementWindowShowLoginPrompt() +- && (/*IsStartupMode() || */ (qgetenv("USER") == "lightdm"))) { ++ if (m_modelLockDialog->getAgreementWindowShowLoginPrompt() && (IsStartupMode() || isGreeterMode())) { + bool hideTitle = m_modelLockDialog->getAgreementWindowHideTitle(); + QString title = m_modelLockDialog->getAgreementWindowPromptTitle(); + QString text = m_modelLockDialog->getAgreementWindowText(); +@@ -124,7 +123,7 @@ void FullBackgroundWidget::initUI() + if (!text.isEmpty() && (hideTitle || (!hideTitle && !text.isEmpty()))) { + m_agreementWindow = new AgreementWindow(hideTitle, title, text, this); + m_lockWidget->hide(); +- m_agreementWindow->setGeometry(this->geometry()); ++ m_agreementWindow->setGeometry(m_lockWidget->geometry()); + m_agreementWindow->show(); + + m_lockWidget->clearFocus(); +@@ -254,6 +253,7 @@ void FullBackgroundWidget::onSecondRunParam(const QString &str) + } else if (str == "ScreensaverLock") { + onShowLockScreensaver(); + } else if (str == "StartupLock") { ++ setIsStartupMode(true); + onShowLock(true); + } else if (str == "CmdLock") { + onShowLock(false); +@@ -342,6 +342,7 @@ void FullBackgroundWidget::onShowBlankScreensaver(int nDelay, bool isHasLock) + + void FullBackgroundWidget::onShowLock(bool isStartup) + { ++ Q_UNUSED(isStartup); + if (m_isSessionTools) { + m_isSessionTools = false; + if (m_lockWidget && !m_lockWidget->isHidden()) +@@ -349,8 +350,8 @@ void FullBackgroundWidget::onShowLock(bool isStartup) + } + + screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK); +- m_isStartupMode = isStartup; + show(); ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] set current user!!"); + Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName()); + Q_EMIT m_modelLockDialog->lockStateChanged(true, false); + if (m_lockWidget && !m_lockWidget->isHidden()) +@@ -521,6 +522,9 @@ void FullBackgroundWidget::onLockScreenTimeout() + void FullBackgroundWidget::onCloseScreensaver() + { + hide(); ++ if (m_lockWidget) { ++ m_lockWidget->exitSubWidget(false, false); ++ } + Q_EMIT m_modelLockDialog->lockStateChanged(false, false); + stopDelayLockScreen(); + screenStatus = UNDEFINED; +@@ -644,6 +648,9 @@ void FullBackgroundWidget::moveToPrimaryScreen() + for (auto screen : QGuiApplication::screens()) { + if (screen == qApp->primaryScreen()) { + qInfo() << "LockWidget:" << screen->geometry() << m_lockWidget->geometry() << geometry(); ++ if (m_agreementWindow && m_agreementWindow->isVisible()) { ++ m_agreementWindow->setGeometry(screen->geometry()); ++ } + if (!m_lockWidget->isHidden()) { + m_lockWidget->hide(); + m_lockWidget->setGeometry(screen->geometry()); +@@ -661,6 +668,9 @@ void FullBackgroundWidget::moveToPrimaryScreen() + /*避免切换时闪烁*/ + qInfo() << "LockWidget:" << screen->geometry() << m_lockWidget->geometry() << "," << screen + << geometry(); ++ if (m_agreementWindow && m_agreementWindow->isVisible()) { ++ m_agreementWindow->setGeometry(screen->geometry()); ++ } + if (!m_lockWidget->isHidden()) { + m_lockWidget->hide(); + m_lockWidget->setGeometry(screen->geometry()); +@@ -717,8 +727,9 @@ void FullBackgroundWidget::keyReleaseEvent(QKeyEvent *e) + bool canShow = true; + if (m_lockWidget && !m_lockWidget->exitSubWidget()) + canShow = false; +- if (canShow) ++ if (canShow && !isGreeterMode()) { + onShowScreensaver(); ++ } + } else if (screenStatus & SCREEN_SAVER /* && !isBlank*/) { + onClearScreensaver(); + } +@@ -819,6 +830,9 @@ void FullBackgroundWidget::onCurUserChanged(const QString &strUserName) + + void FullBackgroundWidget::onAuthSucceed(QString strUserName) + { ++ if (IsStartupMode()) { ++ setIsStartupMode(false); ++ } + if (getenv("USER") == strUserName) { + if (UniAuthService::instance()) { + UniAuthService::instance()->SaveLastLoginUser(strUserName); +@@ -1201,3 +1215,9 @@ void FullBackgroundWidget::onScreensChanged(QList<QString> listMonitors) + // 分辨率,延时1000ms正常。 + QTimer::singleShot(1000, this, SLOT(onDesktopResized())); + } ++ ++void FullBackgroundWidget::setIsStartupMode(bool isStartup) ++{ ++ m_isStartupMode = isStartup; ++ Q_EMIT StartupModeChanged(m_isStartupMode); ++} +diff --git a/src/widgets/fullbackgroundwidget.h b/src/widgets/fullbackgroundwidget.h +index 339d3fc..3c2e9fe 100644 +--- a/src/widgets/fullbackgroundwidget.h ++++ b/src/widgets/fullbackgroundwidget.h +@@ -45,7 +45,7 @@ class FullBackgroundWidget : public QWidget, public QAbstractNativeEventFilter + { + Q_OBJECT + public: +- explicit FullBackgroundWidget(LockDialogModel *model, QWidget *parent = nullptr); ++ explicit FullBackgroundWidget(LockDialogModel *model, bool isStartup = false, QWidget *parent = nullptr); + ~FullBackgroundWidget(); + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; + +@@ -98,6 +98,7 @@ public Q_SLOTS: + + void onStartFcitx(); + Q_SIGNALS: ++ void StartupModeChanged(bool isStartup); + + protected: + void mousePressEvent(QMouseEvent *e); +@@ -131,6 +132,8 @@ private: + void onLockScreenTimeout(); + void stopDelayLockScreen(); + ++ void setIsStartupMode(bool isStartup); ++ + private Q_SLOTS: + void onGlobalKeyPress(const quint8 &key); + void onGlobalKeyRelease(const quint8 &key); +diff --git a/src/widgets/iconedit.cpp b/src/widgets/iconedit.cpp +index a2b46d6..4c13490 100644 +--- a/src/widgets/iconedit.cpp ++++ b/src/widgets/iconedit.cpp +@@ -172,12 +172,15 @@ bool IconEdit::eventFilter(QObject *obj, QEvent *event) + if (event->type() == 2) { + } + } ++ //导致出现按回车发送多次密码问题,因此注释 ++ /* + if (obj == m_iconButton && event->type() == QEvent::KeyRelease) { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { + clicked_cb(); + } + } ++ */ + return false; + } + +diff --git a/src/widgets/lockwidget.cpp b/src/widgets/lockwidget.cpp +index 8c3b318..916d0f3 100644 +--- a/src/widgets/lockwidget.cpp ++++ b/src/widgets/lockwidget.cpp +@@ -58,6 +58,7 @@ + #include "configuration.h" + #include "utils.h" + #include "resetpwdwidget.h" ++#include <syslog.h> + + #define BLUR_RADIUS 300 + #define RIGHT_MARGIN 24 +@@ -67,9 +68,7 @@ + #define IMAGE_DIR PREFIX + "/images/" + float scale; + LockWidget::LockWidget(LockDialogModel *model, QWidget *parent) +- : QWidget(parent) +- , m_modelLockDialog(model) +- , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this)) ++ : QWidget(parent), m_modelLockDialog(model), m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this)) + { + scale = 1.0; + m_curUserInfo = m_modelLockDialog->findUserByName(m_modelLockDialog->defaultUserName()); +@@ -140,12 +139,12 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard) + return false; + } + bool allExited = true; +- if (m_userListWidget && m_userListWidget->isVisible()) { ++ if (m_userListWidget && !m_userListWidget->isHidden()) { + m_userListWidget->hide(); + m_userButton->setClickedStatus(NORMAL); + allExited = false; + } +- if (m_powerListWidget && m_powerListWidget->isVisible()) { ++ if (m_powerListWidget && !m_powerListWidget->isHidden()) { + authDialog->setFocus(); + authDialog->inhibitShow(false); + if (m_isShowResetPasswdBtn) { +@@ -156,45 +155,45 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard) + } + m_powerListWidget->hide(); + buttonListWidget->show(); +- if (m_systemMonitorBtn && m_systemMonitorBtn->isVisible()) { ++ if (m_systemMonitorBtn && !m_systemMonitorBtn->isHidden()) { + m_systemMonitorBtn->hide(); + } + m_powerManagerButton->setClickedStatus(NORMAL); + allExited = false; + } +- if (m_networkWidget && m_networkWidget->isVisible()) { ++ if (m_networkWidget && !m_networkWidget->isHidden()) { + m_networkWidget->hide(); + m_networkButton->setClickedStatus(NORMAL); + // sendNetPluginVisible(false); + allExited = false; + } +- if (hideVirkeyboard && m_virtualKeyboardWidget && m_virtualKeyboardWidget->isVisible()) { ++ if (hideVirkeyboard && m_virtualKeyboardWidget && !m_virtualKeyboardWidget->isHidden()) { + m_virtualKeyboardWidget->hide(); + m_virKbButton->setClickedStatus(NORMAL); + allExited = false; + } +- if (batteryWidget && batteryWidget->isVisible()) { ++ if (batteryWidget && !batteryWidget->isHidden()) { + batteryWidget->hide(); + m_batteryonButton->setClickedStatus(NORMAL); + allExited = false; + } +- if (m_sessionListWidget && m_sessionListWidget->isVisible()) { ++ if (m_sessionListWidget && !m_sessionListWidget->isHidden()) { + m_sessionListWidget->hide(); + m_sessionButton->setClickedStatus(NORMAL); + allExited = false; + } +- if (m_blockWidget && m_blockWidget->isVisible()) { ++ if (m_blockWidget && !m_blockWidget->isHidden()) { + m_blockWidget->hide(); + m_timeWidget->show(); + m_powerListWidget->show(); + buttonListWidget->show(); + allExited = false; + } +- if (m_pResetPwdWidget && m_pResetPwdWidget->isVisible()) { ++ if (m_pResetPwdWidget && m_pResetPwdWidget->isHidden()) { + m_pResetPwdWidget->hide(); + m_pResetPwdWidget->switchToConfidentialDig(); + authDialog->setFocus(); +- authDialog->show(); ++ authDialog->inhibitShow(false); + if (m_pResetPwdBtn) { + m_pResetPwdBtn->show(); + } +@@ -252,8 +251,11 @@ void LockWidget::resizeEvent(QResizeEvent *event) + m_pBottomWidget->setGeometry(0, height() - buttonListWidget->height() - BOTTOM_MARGIN * scale, this->width(), 64); + + if (m_pResetPwdBtn) { +- m_pResetPwdBtn->setGeometry((this->width() - m_pResetPwdBtn->width()) / 2, height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale + 8, +- m_pResetPwdBtn->width(), m_pResetPwdBtn->height()); ++ m_pResetPwdBtn->setGeometry( ++ (this->width() - m_pResetPwdBtn->width()) / 2, ++ height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale + 8, ++ m_pResetPwdBtn->width(), ++ m_pResetPwdBtn->height()); + } + + if (m_sessionListWidget) { +@@ -565,7 +567,7 @@ void LockWidget::initButtonWidget() + }); + } + #endif +- ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] init net icon begin!!"); + m_networkButton = new NetWorkButton(this); + QListWidgetItem *buttonItem = new QListWidgetItem(); + buttonItem->setSizeHint(QSize(48, 48)); +@@ -574,6 +576,7 @@ void LockWidget::initButtonWidget() + buttonListWidget->addItem(buttonItem); + m_networkButton->setToolTip(tr("Network")); + connect(m_networkButton, &NetWorkButton::clicked, this, [this]() { onShowNetworkWidget(); }); ++ syslog(LOG_INFO, "[ukui-screensaver-dialog] init net icon end!!"); + + /* + connect(buttonWidget, &KyNetworkIcon::updateIconHidden +@@ -1068,13 +1071,18 @@ void LockWidget::onShowResetPasswdBtn() + m_pResetPwdBtn->setMinimumWidth(120); + m_pResetPwdBtn->setText(tr("Reset Pwd")); + m_pResetPwdBtn->adjustSize(); +- m_pResetPwdBtn->setStyleSheet( +- "QPushButton{background: rgba(255, 255, 255, 0);border-radius: 24px;color: white;padding-left: 8px; padding-right: 8px;}" +- "QPushButton:hover{background: rgba(255, 255, 255, 0.15);border-radius: 24px;padding-left: 8px; padding-right: 8px;}" +- "QPushButton:pressed {background: rgba(255, 255, 255, 0.4);border-radius: 24px;padding-left: 8px; padding-right: 8px;}"); ++ m_pResetPwdBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0);border-radius: 24px;color: " ++ "white;padding-left: 8px; padding-right: 8px;}" ++ "QPushButton:hover{background: rgba(255, 255, 255, 0.15);border-radius: " ++ "24px;padding-left: 8px; padding-right: 8px;}" ++ "QPushButton:pressed {background: rgba(255, 255, 255, 0.4);border-radius: " ++ "24px;padding-left: 8px; padding-right: 8px;}"); + connect(m_pResetPwdBtn, &QPushButton::clicked, this, &LockWidget::onShowResetPwdWidget); +- m_pResetPwdBtn->setGeometry((this->width() - m_pResetPwdBtn->width()) / 2, height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale - 8, +- m_pResetPwdBtn->width(), m_pResetPwdBtn->height()); ++ m_pResetPwdBtn->setGeometry( ++ (this->width() - m_pResetPwdBtn->width()) / 2, ++ height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale - 8, ++ m_pResetPwdBtn->width(), ++ m_pResetPwdBtn->height()); + } + m_pResetPwdBtn->show(); + m_isShowResetPasswdBtn = true; +@@ -1114,10 +1122,7 @@ void LockWidget::onShowResetPwdWidget() + m_pResetPwdWidget->setFixedWidth(width()); + m_pResetPwdWidget->updateResetPwdSize(); + m_pResetPwdWidget->setGeometry( +- 0, +- (59 * scale + m_timeWidget->height()), +- width(), +- height() - (59 * scale + m_timeWidget->height() + 70)); ++ 0, (59 * scale + m_timeWidget->height()), width(), height() - (59 * scale + m_timeWidget->height() + 70)); + m_pResetPwdWidget->hide(); + } + m_pResetPwdWidget->updateFontSize(m_curFontSize); +@@ -1132,7 +1137,7 @@ void LockWidget::onShowResetPwdWidget() + + void LockWidget::onBackToAuthDialog(bool isSuccess) + { +- authDialog->show(); ++ authDialog->inhibitShow(false); + authDialog->setFocus(); + if (m_pResetPwdWidget) + m_pResetPwdWidget->hide(); +@@ -1282,7 +1287,7 @@ void LockWidget::onShowPowerListWidget(bool issessionTools) + } else { + m_powerListWidget->hide(); + authDialog->inhibitShow(false); +- //bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新 ++ // bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新 + authDialog->update(); + authDialog->setFocus(); + if (m_isShowResetPasswdBtn) { +@@ -1861,8 +1866,9 @@ void LockWidget::setrootWindow(QList<QPair<QRect, QRect>> screenRectList) + + void LockWidget::reloadRootBackground() + { +- if (!isGreeterMode()) ++ if (!isGreeterMode() || m_modelLockDialog->isUseWayland()) { + return; ++ } + // 记录当前的屏幕信息,写入QList保存,防止线程中在遍历屏幕信息时,因 + // 屏幕插拔而崩溃 + m_screenRectList.clear(); +@@ -1885,6 +1891,9 @@ void LockWidget::reloadRootBackground() + + void LockWidget::drawRootBackground() + { ++ if (m_modelLockDialog->isUseWayland()) { ++ return; ++ } + drawBackground(true); + } + +diff --git a/src/widgets/screensaverwidget.cpp b/src/widgets/screensaverwidget.cpp +index cc9b494..0d6239d 100644 +--- a/src/widgets/screensaverwidget.cpp ++++ b/src/widgets/screensaverwidget.cpp +@@ -36,9 +36,12 @@ ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent) + setMouseTracking(true); + setFocus(); + this->installEventFilter(this); ++ if (screensaver) { ++ screensaver->setParent(this); ++ } + + QPalette pal(palette()); +- pal.setColor(QPalette::Background, Qt::black); //设置背景黑色 ++ pal.setColor(QPalette::Background, Qt::black); // 设置背景黑色 + setAutoFillBackground(true); + setPalette(pal); + +diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt +new file mode 100644 +index 0000000..eeca582 +--- /dev/null ++++ b/tests/CMakeLists.txt +@@ -0,0 +1,50 @@ ++add_subdirectory(unit_test_biometric_helper) ++add_subdirectory(unit_test_account_helper) ++add_subdirectory(unit_test_freedesktop_helper) ++add_subdirectory(unit_test_kglobalaccel_helper) ++add_subdirectory(unit_test_login1_helper) ++add_subdirectory(unit_test_session_helper) ++add_subdirectory(unit_test_systemupgrade_helper) ++add_subdirectory(unit_test_uniauth_service) ++add_subdirectory(unit_test_usd_helper) ++add_subdirectory(unit_test_gsettings_helper) ++add_subdirectory(unit_test_engine_device) ++add_subdirectory(unit_test_inputswitch_event) ++add_subdirectory(unit_test_auth_pam) ++add_subdirectory(unit_test_common) ++add_subdirectory(unit_test_switch_user) ++add_subdirectory(unit_test_session_watcher) ++add_subdirectory(unit_test_display_service) ++add_subdirectory(unit_test_dbus_interface) ++add_subdirectory(unit_test_backend_dbus) ++add_subdirectory(unit_test_lock_dialog_model) ++add_subdirectory(unit_test_personal_data) ++add_subdirectory(unit_test_screensaver) ++add_subdirectory(unit_test_screenlock) ++ ++# 处理打桩工具相关配置 ++set(TEST_UTILS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/kt-test-utils") ++ ++# 收集打桩工具的头文件,递归查找符合条件的头文件 ++file(GLOB_RECURSE UTILS_HEADERS ++ "${TEST_UTILS_PATH}/cpp-stub/*.h" ++ "${TEST_UTILS_PATH}/cpp-stub/*.hpp" ++ "${TEST_UTILS_PATH}/cpp-stub-ext/*.h" ++) ++ ++# 收集打桩工具的源文件,递归查找符合条件的源文件 ++file(GLOB_RECURSE UTILS_SOURCES ++ "${TEST_UTILS_PATH}/cpp-stub/*.cpp" ++ "${TEST_UTILS_PATH}/cpp-stub-ext/*.cpp" ++) ++ ++# 创建一个库(这里以静态库为例,可以根据需求改为共享库等)来存放打桩工具相关代码 ++add_library(utils_lib STATIC ${UTILS_SOURCES} ${UTILS_HEADERS}) ++ ++# 将打桩工具库的头文件目录添加到包含路径,方便其他目标使用 ++target_include_directories(utils_lib ++ PUBLIC ++ "${TEST_UTILS_PATH}/cpp-stub" ++ "${TEST_UTILS_PATH}/cpp-stub-ext" ++) ++ +diff --git a/tests/auto_test.sh b/tests/auto_test.sh +new file mode 100755 +index 0000000..6fde6ac +--- /dev/null ++++ b/tests/auto_test.sh +@@ -0,0 +1,56 @@ ++#!/bin/bash ++ ++# 设置退出脚本当命令失败时 (非零退出状态) ++#set -e ++ ++# 函数:运行单元测试 ++run_unit_tests() { ++ local pattern="unit_test_*" ++ ++ # 遍历所有匹配模式的目录 ++ for dir in $pattern; do ++ if [ -d "$dir" ] && [ -x "$dir/$(basename "$dir")" ]; then ++ echo "Running tests in $dir..." ++ # 执行单元测试 ++ (cd "$dir" && "./$(basename "$dir")") ++ # 收集代码覆盖率数据 ++ echo "Collecting coverage data..." ++ (cd "$dir" && (find ./ -name '*.o' | xargs gcov --preserve-paths)) ++ else ++ echo "Skipping non-existent or non-executable directory: $dir, $dir/$(basename "$dir")" ++ fi ++ done ++} ++ ++# 上传 result.zip 到平台 ++URL=$1 ++upload_result() { ++ echo "current pwd : $(pwd)" ++ # 收集覆盖率信息 ++ lcov -d . -c -o r.info ++ ++ # 删除不需要的文件或路径 ++ lcov -r r.info "$(pwd)/unit_test_*" "$(pwd)/../registeredSession/universalinterface.cpp" "/usr/include/*" "/opt/*" -o coverage.info ++ ++ # 生成html覆盖率报告 ++ genhtml "$(pwd)/coverage.info" -o result ++ ++ # 打包 ++ zip -r result.zip result ++ # 上传平台 ++ curl --insecure -X POST -F "file=@/$(pwd)/result.zip" -F "package=ukui-control-center" -F "username=hesisheng" $URL ++ echo "all parameter : $@" ++} ++ ++# 编译项目 ++echo "Compiling the project..." ++cmake . && make ++ ++# 运行各个单元测试 ++echo "Running unit tests..." ++run_unit_tests ++ ++# 上传到平台 ++#upload_result ++ ++echo "All tests have been run successfully, and coverage data has been collected." +diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp +new file mode 100644 +index 0000000..ff21dcd +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp +@@ -0,0 +1,58 @@ ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++#include "stub-shadow.h" ++ ++namespace stub_ext { ++ ++WrapperMap stub_wrappers; ++ ++Wrapper::Wrapper() ++{ ++ ++} ++ ++Wrapper::~Wrapper() ++{ ++ ++} ++ ++void freeWrapper(Wrapper *wrapper) ++{ ++ if (!wrapper) ++ return; ++ ++ for (auto iter = stub_wrappers.begin(); iter != stub_wrappers.end();) { ++ if (iter->second == wrapper) ++ iter = stub_wrappers.erase(iter); ++ else ++ ++iter; ++ } ++ ++ delete wrapper; ++} ++} ++ +diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h +new file mode 100644 +index 0000000..04e746e +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h +@@ -0,0 +1,171 @@ ++ ++#ifndef STUBSHADOW_H ++#define STUBSHADOW_H ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++#include <unordered_map> ++#include <assert.h> ++ ++namespace stub_ext { ++ ++#define LAMDA_FUNCTION_TYPE decltype(&Lamda::operator()) ++ ++class Wrapper ++{ ++public: ++ Wrapper(); ++ virtual ~Wrapper(); ++}; ++ ++typedef std::unordered_map<long, Wrapper* > WrapperMap; ++extern WrapperMap stub_wrappers; ++ ++template<class Lamda> ++class LamdaWrapper : public Wrapper ++{ ++public: ++ LamdaWrapper(Lamda func): Wrapper(),_func(func){} ++ ~LamdaWrapper(){} ++ Lamda _func; ++}; ++ ++template <typename Func> ++struct VFLocator ++{ ++ ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct VFLocator<Ret (Obj::*)(Args...)> ++{ ++ typedef Ret (*Func)(Obj*, Args...); ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct VFLocator<Ret (Obj::*)(Args...) const> ++{ ++ typedef Ret (*Func)(Obj*, Args...); ++}; ++ ++template <typename Func> ++struct LamdaCaller ++{ ++ ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct LamdaCaller<Ret (Obj::*)(Args...) const> ++{ ++ template<class Lamda, typename ...OrgArgs> ++ static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args) ++ { ++ return wrapper->_func(std::forward<OrgArgs>(args)...); ++ } ++}; ++ ++template <class Obj, typename Ret> ++struct LamdaCaller<Ret (Obj::*)() const> ++{ ++ template<class Lamda, typename ...OrgArgs> ++ static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args) ++ { ++ return wrapper->_func(); ++ } ++}; ++ ++template<typename Func, class Lamda> ++struct FuncShadow ++{ ++ ++}; ++ ++template<typename Ret, typename... Args, class Lamda> ++struct FuncShadow<Ret (*)(Args...), Lamda> ++{ ++ typedef Ret (*Shadow)(Args...); ++ typedef Ret RetType; ++ ++ static Ret call(Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, args...); ++ } ++}; ++ ++template<typename Ret, class Obj,typename... Args, class Lamda> ++struct FuncShadow<Ret (Obj::*)(Args...), Lamda> ++{ ++ typedef Ret (*Shadow)(Obj *,Args...); ++ typedef Ret RetType; ++ static Ret call(Obj *obj, Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...); ++ } ++}; ++ ++ ++template<typename Ret, class Obj,typename... Args, class Lamda> ++struct FuncShadow<Ret (Obj::*)(Args...) const, Lamda> ++{ ++ typedef Ret (*Shadow)(Obj *,Args...); ++ typedef Ret RetType; ++ static Ret call(Obj *obj, Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...); ++ } ++}; ++ ++template<typename Func, class Lamda> ++typename FuncShadow<Func, Lamda>::Shadow depictShadow(Wrapper **wrapper, Func func, Lamda lamda) ++{ ++ *wrapper = new LamdaWrapper<Lamda>(lamda); ++ typename FuncShadow<Func,Lamda>::Shadow shadow = &FuncShadow<Func,Lamda>::call; ++ long id = (long)shadow; ++ assert(stub_wrappers.find(id) == stub_wrappers.end()); ++ stub_wrappers.insert(std::make_pair(id,*wrapper)); ++ return shadow; ++} ++ ++void freeWrapper(Wrapper *wrapper); ++ ++} ++ ++#endif // STUBSHADOW_H +diff --git a/tests/kt-test-utils/cpp-stub-ext/stubext.h b/tests/kt-test-utils/cpp-stub-ext/stubext.h +new file mode 100644 +index 0000000..2a70a78 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stubext.h +@@ -0,0 +1,129 @@ ++ ++#ifndef STUBEXT_H ++#define STUBEXT_H ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++//需修改Stub的私用成员函数和成员变量为保护类型 ++#include "stub.h" ++ ++#include "stub-shadow.h" ++ ++#ifdef DEBUG_STUB_INVOKE ++// use to make sure the stub function is invoked. ++# define __DBG_STUB_INVOKE__ printf("stub at %s:%d is invoked.\n", __FILE__, __LINE__); ++#else ++# define __DBG_STUB_INVOKE__ ++#endif ++ ++#define VADDR(CLASS_NAME, MEMBER_NAME) (typename stub_ext::VFLocator<decltype(&CLASS_NAME::MEMBER_NAME)>::Func)(&CLASS_NAME::MEMBER_NAME) ++ ++namespace stub_ext { ++ ++class StubExt : public Stub ++{ ++public: ++ StubExt() ++ : Stub() { } ++ ++ template<typename T, class Lamda> ++ bool set_lamda(T addr, Lamda lamda) ++ { ++ char *fn = addrof(addr); ++ if (m_result.find(fn) != m_result.end()) ++ reset(addr); ++ ++ Wrapper *wrapper = nullptr; ++ auto addr_stub = depictShadow(&wrapper, addr, lamda); ++ if (set(addr, addr_stub)) { ++ m_wrappers.insert(std::make_pair(fn, wrapper)); ++ return true; ++ } else { ++ freeWrapper(wrapper); ++ } ++ return false; ++ } ++ ++ template<typename T> ++ void reset(T addr) ++ { ++ Stub::reset(addr); ++ char *fn = addrof(addr); ++ auto iter = m_wrappers.find(fn); ++ if (iter != m_wrappers.end()) { ++ freeWrapper(iter->second); ++ m_wrappers.erase(iter); ++ } ++ } ++ ++ ~StubExt() ++ { ++ clear(); ++ } ++ ++ void clear() override ++ { ++ Stub::clear(); ++ for (auto iter = m_wrappers.begin(); iter != m_wrappers.end(); ++iter) { ++ freeWrapper(iter->second); ++ } ++ m_wrappers.clear(); ++ } ++ ++ template<class T> ++ static void *get_ctor_addr(bool start = true) ++ { ++ // the start vairable must be true, or the compiler will optimize out. ++ if (start) goto Start; ++ Call_Constructor: ++ // This line of code will not be executed. ++ // The purpose of the code is to allow the compiler to generate the assembly code that calls the constructor. ++ T(); ++ Start: ++ // The address of the line of code T() obtained by assembly ++ char *p = (char *)&&Call_Constructor; // https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html ++ // CALL rel32 ++ void *ret = 0; ++ char pos; ++ char call = 0xe8; ++ do { ++ pos = *p; ++ if (pos == call) { ++ ret = p + 5 + (*(int *)(p + 1)); ++ } ++ ++ } while (!ret && (++p)); ++ ++ return ret; ++ } ++ ++protected: ++ std::map<char *, Wrapper *> m_wrappers; ++}; ++ ++} ++ ++#endif // STUBEXT_H +diff --git a/tests/kt-test-utils/cpp-stub/addr_any.h b/tests/kt-test-utils/cpp-stub/addr_any.h +new file mode 100644 +index 0000000..a153f34 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/addr_any.h +@@ -0,0 +1,280 @@ ++#ifndef __ADDR_ANY_H__ ++#define __ADDR_ANY_H__ ++ ++ ++//linux ++#include <regex.h> ++#include <cxxabi.h> ++//c ++#include <cinttypes> ++#include <cstdio> ++#include <cstdlib> ++ ++//c++ ++#include <string> ++#include <map> ++//project ++#include "elfio.hpp" ++ ++ ++ ++class AddrAny ++{ ++public: ++ AddrAny() ++ { ++ m_init = get_exe_pathname(m_fullname); ++ m_baseaddr = 0; ++ } ++ AddrAny(std::string libname) ++ { ++ m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr); ++ } ++ ++ int get_local_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result); ++ } ++ int get_global_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result); ++ } ++ int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result); ++ } ++ ++ int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result); ++ } ++ int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result); ++ } ++ ++private: ++ bool demangle(std::string& s, std::string& name) { ++ int status; ++ char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status); ++ if (status != 0) ++ { ++ switch(status) ++ { ++ case -1: name = "memory allocation error"; break; ++ case -2: name = "invalid name given"; break; ++ case -3: name = "internal error: __cxa_demangle: invalid argument"; break; ++ default: name = "unknown error occured"; break; ++ } ++ return false; ++ } ++ name = pname; ++ free(pname); ++ return true; ++ } ++ bool get_exe_pathname( std::string& name) ++ { ++ char line[512]; ++ FILE *fp; ++ uintptr_t base_addr; ++ char perm[5]; ++ unsigned long offset; ++ int pathname_pos; ++ char *pathname; ++ size_t pathname_len; ++ int match = 0; ++ ++ if(NULL == (fp = fopen("/proc/self/maps", "r"))) ++ { ++ return false; ++ } ++ ++ while(fgets(line, sizeof(line), fp)) ++ { ++ if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; ++ ++ if(0 != offset) continue; ++ ++ //get pathname ++ while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) ++ pathname_pos += 1; ++ if(pathname_pos >= (int)(sizeof(line) - 1)) continue; ++ pathname = line + pathname_pos; ++ pathname_len = strlen(pathname); ++ if(0 == pathname_len) continue; ++ if(pathname[pathname_len - 1] == '\n') ++ { ++ pathname[pathname_len - 1] = '\0'; ++ pathname_len -= 1; ++ } ++ if(0 == pathname_len) continue; ++ if('[' == pathname[0]) continue; ++ ++ name = pathname; ++ match = 1; ++ break; ++ ++ } ++ fclose(fp); ++ ++ if(0 == match) ++ { ++ return false; ++ } ++ else ++ { ++ return true; ++ } ++ ++ } ++ ++ bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr) ++ { ++ char line[512]; ++ FILE *fp; ++ uintptr_t base_addr; ++ char perm[5]; ++ unsigned long offset; ++ int pathname_pos; ++ char *pathname; ++ size_t pathname_len; ++ int match; ++ regex_t pathname_regex; ++ ++ regcomp(&pathname_regex, pathname_regex_str.c_str(), 0); ++ ++ if(NULL == (fp = fopen("/proc/self/maps", "r"))) ++ { ++ return false; ++ } ++ ++ while(fgets(line, sizeof(line), fp)) ++ { ++ if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; ++ ++ //check permission ++ if(perm[0] != 'r') continue; ++ if(perm[3] != 'p') continue; //do not touch the shared memory ++ ++ //check offset ++ // ++ //We are trying to find ELF header in memory. ++ //It can only be found at the beginning of a mapped memory regions ++ //whose offset is 0. ++ if(0 != offset) continue; ++ ++ //get pathname ++ while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) ++ pathname_pos += 1; ++ if(pathname_pos >= (int)(sizeof(line) - 1)) continue; ++ pathname = line + pathname_pos; ++ pathname_len = strlen(pathname); ++ if(0 == pathname_len) continue; ++ if(pathname[pathname_len - 1] == '\n') ++ { ++ pathname[pathname_len - 1] = '\0'; ++ pathname_len -= 1; ++ } ++ if(0 == pathname_len) continue; ++ if('[' == pathname[0]) continue; ++ ++ //check pathname ++ //if we need to hook this elf? ++ match = 0; ++ if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0)) ++ { ++ match = 1; ++ name = pathname; ++ addr = (unsigned long)base_addr; ++ break; ++ } ++ if(0 == match) continue; ++ ++ } ++ fclose(fp); ++ if(0 == match) ++ { ++ return false; ++ } ++ else ++ { ++ return true; ++ } ++ ++ } ++ ++ int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ // Create an elfio reader ++ ELFIO::elfio reader; ++ int count = 0; ++ regex_t pathname_regex; ++ ++ if(!m_init) ++ { ++ return -1; ++ } ++ ++ regcomp(&pathname_regex, func_name_regex_str.c_str(), 0); ++ // Load ELF data ++ if(!reader.load(m_fullname.c_str())) ++ { ++ return -1; ++ } ++ ++ ELFIO::Elf_Half sec_num = reader.sections.size(); ++ for(int i = 0; i < sec_num; ++i) ++ { ++ ELFIO::section* psec = reader.sections[i]; ++ // Check section type ++ if(psec->get_type() == ttype) ++ { ++ const ELFIO::symbol_section_accessor symbols( reader, psec ); ++ for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) ++ { ++ std::string name; ++ std::string name_mangle; ++ ELFIO::Elf64_Addr value; ++ ELFIO::Elf_Xword size; ++ unsigned char bind; ++ unsigned char type; ++ ELFIO::Elf_Half section_index; ++ unsigned char other; ++ ++ // Read symbol properties ++ symbols.get_symbol( j, name, value, size, bind, type, section_index, other ); ++ if(type == STT_FUNC && bind == stype) ++ { ++ bool ret = demangle(name,name_mangle); ++ if(ret == true) ++ { ++ if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0)) ++ { ++ result.insert ( std::pair<std::string,void *>(name_mangle,(void*)(value + m_baseaddr))); ++ count++; ++ } ++ } ++ else ++ { ++ if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0)) ++ { ++ result.insert ( std::pair<std::string,void *>(name,(void*)(value + m_baseaddr))); ++ count++; ++ } ++ } ++ } ++ } ++ break; ++ } ++ } ++ ++ return count; ++ } ++private: ++ bool m_init; ++ std::string m_name; ++ std::string m_fullname; ++ unsigned long m_baseaddr; ++ ++}; ++#endif +diff --git a/tests/kt-test-utils/cpp-stub/addr_pri.h b/tests/kt-test-utils/cpp-stub/addr_pri.h +new file mode 100644 +index 0000000..9174bb0 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/addr_pri.h +@@ -0,0 +1,177 @@ ++#ifndef __ADDR_PRI_H__ ++#define __ADDR_PRI_H__ ++ ++ ++#include <utility> ++#include <type_traits> ++ ++ ++ ++//base on C++11 ++ ++/********************************************************** ++ access private function ++**********************************************************/ ++ ++ ++namespace std { ++ template <bool B, class T = void> ++ using enable_if_t = typename enable_if<B, T>::type; ++ template <class T> ++ using remove_reference_t = typename remove_reference<T>::type; ++} // std ++ ++// Unnamed namespace is used to avoid duplicate symbols if the macros are used ++namespace { ++ namespace private_access_detail { ++ ++ // @tparam TagType, used to declare different "get" funciton overloads for ++ // different members/statics ++ template <typename PtrType, PtrType PtrValue, typename TagType> ++ struct private_access { ++ // Normal lookup cannot find in-class defined (inline) friend functions. ++ friend PtrType get(TagType) { return PtrValue; } ++ }; ++ ++ } // namespace private_access_detail ++} // namespace ++ ++// Used macro naming conventions: ++// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all ++// macro here has this prefix. ++// All implementation macro, which are not meant to be used directly have the ++// PRIVATE_ACCESS_DETAIL prefix. ++// Some macros have the ABCD_IMPL form, which means they contain the ++// implementation details for the specific ABCD macro. ++ ++#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y ++#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) ++ ++// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of ++// members, or it can be "*" in case of statics. ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \ ++ PtrTypeKind) \ ++ namespace { \ ++ namespace private_access_detail { \ ++ /* Tag type, used to declare different get funcitons for different \ ++ * members \ ++ */ \ ++ struct Tag {}; \ ++ /* Explicit instantiation */ \ ++ template struct private_access<decltype(&Class::Name), &Class::Name, \ ++ Tag>; \ ++ /* We can build the PtrType only with two aliases */ \ ++ /* E.g. using PtrType = int(int) *; would be illformed */ \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \ ++ /* Declare the friend function, now it is visible in namespace scope. \ ++ * Note, \ ++ * we could declare it inside the Tag type too, in that case ADL would \ ++ * find \ ++ * the declaration. By choosing to declare it here, the Tag type remains \ ++ * a \ ++ * simple tag type, it has no other responsibilities. */ \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ ++ namespace { \ ++ namespace access_private_field { \ ++ Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \ ++ Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \ ++ /* The following usings are here to avoid duplicate const qualifier \ ++ * warnings \ ++ */ \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \ ++ const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\ ++ return t.*get(private_access_detail::Tag{}); \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ ++ namespace { \ ++ namespace call_private_fun { \ ++ /* We do perfect forwarding, but we want to restrict the overload set \ ++ * only for objects which have the type Class. */ \ ++ template <typename Obj, \ ++ std::enable_if_t<std::is_same<std::remove_reference_t<Obj>, \ ++ Class>::value> * = nullptr, \ ++ typename... Args> \ ++ auto Class##Name(Obj &&o, Args &&... args) -> decltype( \ ++ (std::forward<Obj>(o).* \ ++ get(private_access_detail::Tag{}))(std::forward<Args>(args)...)) { \ ++ return (std::forward<Obj>(o).*get(private_access_detail::Tag{}))( \ ++ std::forward<Args>(args)...); \ ++ } \ ++ } \ ++ namespace get_private_fun { \ ++ auto Class##Name() -> decltype( \ ++ get(private_access_detail::Tag{})) { \ ++ return (get(private_access_detail::Tag{})); \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \ ++ Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ ++ namespace { \ ++ namespace access_private_static_field { \ ++ namespace Class { \ ++ Type &Class##Name() { return *get(private_access_detail::Tag{}); } \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \ ++ Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ ++ namespace { \ ++ namespace call_private_static_fun { \ ++ namespace Class { \ ++ template <typename... Args> \ ++ auto Class##Name(Args &&... args) -> decltype( \ ++ get(private_access_detail::Tag{})(std::forward<Args>(args)...)) { \ ++ return get(private_access_detail::Tag{})( \ ++ std::forward<Args>(args)...); \ ++ } \ ++ } \ ++ } \ ++ namespace get_private_static_fun { \ ++ namespace Class { \ ++ auto Class##Name() -> decltype(get(private_access_detail::Tag{})) { \ ++ return get(private_access_detail::Tag{}); \ ++ } \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__) ++ ++#define ACCESS_PRIVATE_FIELD(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ ++ Class, Type, Name) ++ ++#define ACCESS_PRIVATE_FUN(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ ++ Class, Type, Name) ++ ++#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \ ++ Type Class::Name; \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \ ++ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) ++ ++#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \ ++ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) ++ ++#endif +diff --git a/tests/kt-test-utils/cpp-stub/elfio.hpp b/tests/kt-test-utils/cpp-stub/elfio.hpp +new file mode 100644 +index 0000000..dd5c9ae +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/elfio.hpp +@@ -0,0 +1,4888 @@ ++ ++/*** Start of inlined file: elfio_dump.hpp ***/ ++#ifndef ELFIO_DUMP_HPP ++#define ELFIO_DUMP_HPP ++ ++#include <algorithm> ++#include <string> ++#include <ostream> ++#include <sstream> ++#include <iomanip> ++ ++/*** Start of inlined file: elfio.hpp ***/ ++#ifndef ELFIO_HPP ++#define ELFIO_HPP ++ ++#ifdef _MSC_VER ++#pragma warning( push ) ++#pragma warning( disable : 4996 ) ++#pragma warning( disable : 4355 ) ++#pragma warning( disable : 4244 ) ++#endif ++ ++#include <string> ++#include <iostream> ++#include <fstream> ++#include <functional> ++#include <algorithm> ++#include <vector> ++#include <deque> ++#include <iterator> ++ ++ ++/*** Start of inlined file: elf_types.hpp ***/ ++#ifndef ELFTYPES_H ++#define ELFTYPES_H ++ ++#ifndef ELFIO_NO_OWN_TYPES ++#if !defined( ELFIO_NO_CSTDINT ) && !defined( ELFIO_NO_INTTYPES ) ++#include <stdint.h> ++#else ++typedef unsigned char uint8_t; ++typedef signed char int8_t; ++typedef unsigned short uint16_t; ++typedef signed short int16_t; ++#ifdef _MSC_VER ++typedef unsigned __int32 uint32_t; ++typedef signed __int32 int32_t; ++typedef unsigned __int64 uint64_t; ++typedef signed __int64 int64_t; ++#else ++typedef unsigned int uint32_t; ++typedef signed int int32_t; ++typedef unsigned long long uint64_t; ++typedef signed long long int64_t; ++#endif // _MSC_VER ++#endif // ELFIO_NO_CSTDINT ++#endif // ELFIO_NO_OWN_TYPES ++ ++namespace ELFIO { ++ ++// Attention! Platform depended definitions. ++typedef uint16_t Elf_Half; ++typedef uint32_t Elf_Word; ++typedef int32_t Elf_Sword; ++typedef uint64_t Elf_Xword; ++typedef int64_t Elf_Sxword; ++ ++typedef uint32_t Elf32_Addr; ++typedef uint32_t Elf32_Off; ++typedef uint64_t Elf64_Addr; ++typedef uint64_t Elf64_Off; ++ ++#define Elf32_Half Elf_Half ++#define Elf64_Half Elf_Half ++#define Elf32_Word Elf_Word ++#define Elf64_Word Elf_Word ++#define Elf32_Sword Elf_Sword ++#define Elf64_Sword Elf_Sword ++ ++/////////////////////// ++// ELF Header Constants ++ ++// File type ++#define ET_NONE 0 ++#define ET_REL 1 ++#define ET_EXEC 2 ++#define ET_DYN 3 ++#define ET_CORE 4 ++#define ET_LOOS 0xFE00 ++#define ET_HIOS 0xFEFF ++#define ET_LOPROC 0xFF00 ++#define ET_HIPROC 0xFFFF ++ ++#define EM_NONE 0 // No machine ++#define EM_M32 1 // AT&T WE 32100 ++#define EM_SPARC 2 // SUN SPARC ++#define EM_386 3 // Intel 80386 ++#define EM_68K 4 // Motorola m68k family ++#define EM_88K 5 // Motorola m88k family ++#define EM_486 6 // Intel 80486// Reserved for future use ++#define EM_860 7 // Intel 80860 ++#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) ++#define EM_S370 9 // IBM System/370 ++#define EM_MIPS_RS3_LE \ ++ 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated ++#define EM_res011 11 // Reserved ++#define EM_res012 12 // Reserved ++#define EM_res013 13 // Reserved ++#define EM_res014 14 // Reserved ++#define EM_PARISC 15 // HPPA ++#define EM_res016 16 // Reserved ++#define EM_VPP550 17 // Fujitsu VPP500 ++#define EM_SPARC32PLUS 18 // Sun's "v8plus" ++#define EM_960 19 // Intel 80960 ++#define EM_PPC 20 // PowerPC ++#define EM_PPC64 21 // 64-bit PowerPC ++#define EM_S390 22 // IBM S/390 ++#define EM_SPU 23 // Sony/Toshiba/IBM SPU ++#define EM_res024 24 // Reserved ++#define EM_res025 25 // Reserved ++#define EM_res026 26 // Reserved ++#define EM_res027 27 // Reserved ++#define EM_res028 28 // Reserved ++#define EM_res029 29 // Reserved ++#define EM_res030 30 // Reserved ++#define EM_res031 31 // Reserved ++#define EM_res032 32 // Reserved ++#define EM_res033 33 // Reserved ++#define EM_res034 34 // Reserved ++#define EM_res035 35 // Reserved ++#define EM_V800 36 // NEC V800 series ++#define EM_FR20 37 // Fujitsu FR20 ++#define EM_RH32 38 // TRW RH32 ++#define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA ++#define EM_RCE 39 // Old name for MCore ++#define EM_ARM 40 // ARM ++#define EM_OLD_ALPHA 41 // Digital Alpha ++#define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH ++#define EM_SPARCV9 43 // SPARC v9 64-bit ++#define EM_TRICORE 44 // Siemens Tricore embedded processor ++#define EM_ARC 45 // ARC Cores ++#define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300 ++#define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H ++#define EM_H8S 48 // Renesas (formerly Hitachi) H8S ++#define EM_H8_500 49 // Renesas (formerly Hitachi) H8/500 ++#define EM_IA_64 50 // Intel IA-64 Processor ++#define EM_MIPS_X 51 // Stanford MIPS-X ++#define EM_COLDFIRE 52 // Motorola Coldfire ++#define EM_68HC12 53 // Motorola M68HC12 ++#define EM_MMA 54 // Fujitsu Multimedia Accelerator ++#define EM_PCP 55 // Siemens PCP ++#define EM_NCPU 56 // Sony nCPU embedded RISC processor ++#define EM_NDR1 57 // Denso NDR1 microprocesspr ++#define EM_STARCORE 58 // Motorola Star*Core processor ++#define EM_ME16 59 // Toyota ME16 processor ++#define EM_ST100 60 // STMicroelectronics ST100 processor ++#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor ++#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor ++#define EM_PDSP 63 // Sony DSP Processor ++#define EM_PDP10 64 // Digital Equipment Corp. PDP-10 ++#define EM_PDP11 65 // Digital Equipment Corp. PDP-11 ++#define EM_FX66 66 // Siemens FX66 microcontroller ++#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller ++#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller ++#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller ++#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller ++#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller ++#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller ++#define EM_SVX 73 // Silicon Graphics SVx ++#define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu ++#define EM_VAX 75 // Digital VAX ++#define EM_CRIS 76 // Axis Communications 32-bit embedded processor ++#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu ++#define EM_FIREPATH 78 // Element 14 64-bit DSP processor ++#define EM_ZSP 79 // LSI Logic's 16-bit DSP processor ++#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor ++#define EM_HUANY 81 // Harvard's machine-independent format ++#define EM_PRISM 82 // SiTera Prism ++#define EM_AVR 83 // Atmel AVR 8-bit microcontroller ++#define EM_FR30 84 // Fujitsu FR30 ++#define EM_D10V 85 // Mitsubishi D10V ++#define EM_D30V 86 // Mitsubishi D30V ++#define EM_V850 87 // NEC v850 ++#define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R) ++#define EM_MN10300 89 // Matsushita MN10300 ++#define EM_MN10200 90 // Matsushita MN10200 ++#define EM_PJ 91 // picoJava ++#define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor ++#define EM_ARC_A5 93 // ARC Cores Tangent-A5 ++#define EM_XTENSA 94 // Tensilica Xtensa Architecture ++#define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor ++#define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor ++#define EM_NS32K 97 // National Semiconductor 32000 series ++#define EM_TPC 98 // Tenor Network TPC processor ++#define EM_SNP1K 99 // Trebia SNP 1000 processor ++#define EM_ST200 100 // STMicroelectronics ST200 microcontroller ++#define EM_IP2K 101 // Ubicom IP2022 micro controller ++#define EM_MAX 102 // MAX Processor ++#define EM_CR 103 // National Semiconductor CompactRISC ++#define EM_F2MC16 104 // Fujitsu F2MC16 ++#define EM_MSP430 105 // TI msp430 micro controller ++#define EM_BLACKFIN 106 // ADI Blackfin ++#define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors ++#define EM_SEP 108 // Sharp embedded microprocessor ++#define EM_ARCA 109 // Arca RISC Microprocessor ++#define EM_UNICORE \ ++ 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University ++#define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU ++#define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor ++#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor ++#define EM_CRX 114 // National Semiconductor CRX ++#define EM_XGATE 115 // Motorola XGATE embedded processor ++#define EM_C166 116 // Infineon C16x/XC16x processor ++#define EM_M16C 117 // Renesas M16C series microprocessors ++#define EM_DSPIC30F \ ++ 118 // Microchip Technology dsPIC30F Digital Signal Controller ++#define EM_CE 119 // Freescale Communication Engine RISC core ++#define EM_M32C 120 // Renesas M32C series microprocessors ++#define EM_res121 121 // Reserved ++#define EM_res122 122 // Reserved ++#define EM_res123 123 // Reserved ++#define EM_res124 124 // Reserved ++#define EM_res125 125 // Reserved ++#define EM_res126 126 // Reserved ++#define EM_res127 127 // Reserved ++#define EM_res128 128 // Reserved ++#define EM_res129 129 // Reserved ++#define EM_res130 130 // Reserved ++#define EM_TSK3000 131 // Altium TSK3000 core ++#define EM_RS08 132 // Freescale RS08 embedded processor ++#define EM_res133 133 // Reserved ++#define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor ++#define EM_SCORE 135 // Sunplus Score ++#define EM_SCORE7 135 // Sunplus S+core7 RISC processor ++#define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor ++#define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor ++#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture ++#define EM_SE_C17 139 // Seiko Epson C17 family ++#define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family ++#define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family ++#define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family ++#define EM_res143 143 // Reserved ++#define EM_res144 144 // Reserved ++#define EM_res145 145 // Reserved ++#define EM_res146 146 // Reserved ++#define EM_res147 147 // Reserved ++#define EM_res148 148 // Reserved ++#define EM_res149 149 // Reserved ++#define EM_res150 150 // Reserved ++#define EM_res151 151 // Reserved ++#define EM_res152 152 // Reserved ++#define EM_res153 153 // Reserved ++#define EM_res154 154 // Reserved ++#define EM_res155 155 // Reserved ++#define EM_res156 156 // Reserved ++#define EM_res157 157 // Reserved ++#define EM_res158 158 // Reserved ++#define EM_res159 159 // Reserved ++#define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor ++#define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor ++#define EM_R32C 162 // Renesas R32C series microprocessors ++#define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family ++#define EM_QDSP6 164 // QUALCOMM DSP6 Processor ++#define EM_8051 165 // Intel 8051 and variants ++#define EM_STXP7X 166 // STMicroelectronics STxP7x family ++#define EM_NDS32 \ ++ 167 // Andes Technology compact code size embedded RISC processor family ++#define EM_ECOG1 168 // Cyan Technology eCOG1X family ++#define EM_ECOG1X 168 // Cyan Technology eCOG1X family ++#define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers ++#define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor ++#define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor ++#define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture ++#define EM_RX 173 // Renesas RX family ++#define EM_METAG 174 // Imagination Technologies META processor architecture ++#define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture ++#define EM_ECOG16 176 // Cyan Technology eCOG16 family ++#define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor ++#define EM_ETPU 178 // Freescale Extended Time Processing Unit ++#define EM_SLE9X 179 // Infineon Technologies SLE9X core ++#define EM_L1OM 180 // Intel L1OM ++#define EM_INTEL181 181 // Reserved by Intel ++#define EM_INTEL182 182 // Reserved by Intel ++#define EM_res183 183 // Reserved by ARM ++#define EM_res184 184 // Reserved by ARM ++#define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family ++#define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller ++#define EM_TILE64 187 // Tilera TILE64 multicore architecture family ++#define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family ++#define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core ++#define EM_CUDA 190 // NVIDIA CUDA architecture ++#define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family ++#define EM_CLOUDSHIELD 192 // CloudShield architecture family ++#define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family ++#define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family ++#define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2 ++#define EM_OPEN8 196 // Open8 8-bit RISC soft processor core ++#define EM_RL78 197 // Renesas RL78 family ++#define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor ++#define EM_78KOR 199 // Renesas 78KOR family ++#define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC) ++#define EM_BA1 201 // Beyond BA1 CPU architecture ++#define EM_BA2 202 // Beyond BA2 CPU architecture ++#define EM_XCORE 203 // XMOS xCORE processor family ++#define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family ++#define EM_INTEL205 205 // Reserved by Intel ++#define EM_INTEL206 206 // Reserved by Intel ++#define EM_INTEL207 207 // Reserved by Intel ++#define EM_INTEL208 208 // Reserved by Intel ++#define EM_INTEL209 209 // Reserved by Intel ++#define EM_KM32 210 // KM211 KM32 32-bit processor ++#define EM_KMX32 211 // KM211 KMX32 32-bit processor ++#define EM_KMX16 212 // KM211 KMX16 16-bit processor ++#define EM_KMX8 213 // KM211 KMX8 8-bit processor ++#define EM_KVARC 214 // KM211 KVARC processor ++#define EM_CDP 215 // Paneve CDP architecture family ++#define EM_COGE 216 // Cognitive Smart Memory Processor ++#define EM_COOL 217 // iCelero CoolEngine ++#define EM_NORC 218 // Nanoradio Optimized RISC ++#define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family ++#define EM_Z80 220 // Zilog Z80 ++#define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor ++#define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture ++#define EM_MOXIE 223 // Moxie processor family ++#define EM_AMDGPU 224 // AMD GPU architecture ++#define EM_RISCV 243 // RISC-V ++#define EM_LANAI 244 // Lanai processor ++#define EM_CEVA 245 // CEVA Processor Architecture Family ++#define EM_CEVA_X2 246 // CEVA X2 Processor Family ++#define EM_BPF 247 // Linux BPF – in-kernel virtual machine ++#define EM_GRAPHCORE_IPU 248 // Graphcore Intelligent Processing Unit ++#define EM_IMG1 249 // Imagination Technologies ++#define EM_NFP 250 // Netronome Flow Processor (P) ++#define EM_CSKY 252 // C-SKY processor family ++ ++// File version ++#define EV_NONE 0 ++#define EV_CURRENT 1 ++ ++// Identification index ++#define EI_MAG0 0 ++#define EI_MAG1 1 ++#define EI_MAG2 2 ++#define EI_MAG3 3 ++#define EI_CLASS 4 ++#define EI_DATA 5 ++#define EI_VERSION 6 ++#define EI_OSABI 7 ++#define EI_ABIVERSION 8 ++#define EI_PAD 9 ++#define EI_NIDENT 16 ++ ++// Magic number ++#define ELFMAG0 0x7F ++#define ELFMAG1 'E' ++#define ELFMAG2 'L' ++#define ELFMAG3 'F' ++ ++// File class ++#define ELFCLASSNONE 0 ++#define ELFCLASS32 1 ++#define ELFCLASS64 2 ++ ++// Encoding ++#define ELFDATANONE 0 ++#define ELFDATA2LSB 1 ++#define ELFDATA2MSB 2 ++ ++// OS extensions ++#define ELFOSABI_NONE 0 // No extensions or unspecified ++#define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX ++#define ELFOSABI_NETBSD 2 // NetBSD ++#define ELFOSABI_LINUX 3 // Linux ++#define ELFOSABI_SOLARIS 6 // Sun Solaris ++#define ELFOSABI_AIX 7 // AIX ++#define ELFOSABI_IRIX 8 // IRIX ++#define ELFOSABI_FREEBSD 9 // FreeBSD ++#define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX ++#define ELFOSABI_MODESTO 11 // Novell Modesto ++#define ELFOSABI_OPENBSD 12 // Open BSD ++#define ELFOSABI_OPENVMS 13 // Open VMS ++#define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel ++#define ELFOSABI_AROS 15 // Amiga Research OS ++#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS ++// 64-255 Architecture-specific value range ++#define ELFOSABI_AMDGPU_HSA \ ++ 64 // AMDGPU OS for HSA compatible compute // kernels. ++#define ELFOSABI_AMDGPU_PAL \ ++ 65 // AMDGPU OS for AMD PAL compatible graphics // shaders and compute kernels. ++#define ELFOSABI_AMDGPU_MESA3D \ ++ 66 // AMDGPU OS for Mesa3D compatible graphics // shaders and compute kernels. ++ ++// AMDGPU specific e_flags ++#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask. ++#define EF_AMDGPU_XNACK \ ++ 0x100 // Indicates if the XNACK target feature is // enabled for all code contained in the ELF. ++// AMDGPU processors ++#define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor. ++#define EF_AMDGPU_MACH_R600_R600 0x001 ++#define EF_AMDGPU_MACH_R600_R630 0x002 ++#define EF_AMDGPU_MACH_R600_RS880 0x003 ++#define EF_AMDGPU_MACH_R600_RV670 0x004 ++#define EF_AMDGPU_MACH_R600_RV710 0x005 ++#define EF_AMDGPU_MACH_R600_RV730 0x006 ++#define EF_AMDGPU_MACH_R600_RV770 0x007 ++#define EF_AMDGPU_MACH_R600_CEDAR 0x008 ++#define EF_AMDGPU_MACH_R600_CYPRESS 0x009 ++#define EF_AMDGPU_MACH_R600_JUNIPER 0x00a ++#define EF_AMDGPU_MACH_R600_REDWOOD 0x00b ++#define EF_AMDGPU_MACH_R600_SUMO 0x00c ++#define EF_AMDGPU_MACH_R600_BARTS 0x00d ++#define EF_AMDGPU_MACH_R600_CAICOS 0x00e ++#define EF_AMDGPU_MACH_R600_CAYMAN 0x00f ++#define EF_AMDGPU_MACH_R600_TURKS 0x010 ++#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011 ++#define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f ++#define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600 ++#define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS ++#define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020 ++#define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021 ++#define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022 ++#define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023 ++#define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024 ++#define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025 ++#define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026 ++#define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028 ++#define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029 ++#define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a ++#define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b ++#define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c ++#define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d ++#define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e ++#define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f ++#define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027 ++#define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030 ++#define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600 ++#define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906 ++ ++///////////////////// ++// Sections constants ++ ++// Section indexes ++#define SHN_UNDEF 0 ++#define SHN_LORESERVE 0xFF00 ++#define SHN_LOPROC 0xFF00 ++#define SHN_HIPROC 0xFF1F ++#define SHN_LOOS 0xFF20 ++#define SHN_HIOS 0xFF3F ++#define SHN_ABS 0xFFF1 ++#define SHN_COMMON 0xFFF2 ++#define SHN_XINDEX 0xFFFF ++#define SHN_HIRESERVE 0xFFFF ++ ++// Section types ++#define SHT_NULL 0 ++#define SHT_PROGBITS 1 ++#define SHT_SYMTAB 2 ++#define SHT_STRTAB 3 ++#define SHT_RELA 4 ++#define SHT_HASH 5 ++#define SHT_DYNAMIC 6 ++#define SHT_NOTE 7 ++#define SHT_NOBITS 8 ++#define SHT_REL 9 ++#define SHT_SHLIB 10 ++#define SHT_DYNSYM 11 ++#define SHT_INIT_ARRAY 14 ++#define SHT_FINI_ARRAY 15 ++#define SHT_PREINIT_ARRAY 16 ++#define SHT_GROUP 17 ++#define SHT_SYMTAB_SHNDX 18 ++#define SHT_LOOS 0x60000000 ++#define SHT_HIOS 0x6fffffff ++#define SHT_LOPROC 0x70000000 ++#define SHT_HIPROC 0x7FFFFFFF ++#define SHT_LOUSER 0x80000000 ++#define SHT_HIUSER 0xFFFFFFFF ++ ++// Section attribute flags ++#define SHF_WRITE 0x1 ++#define SHF_ALLOC 0x2 ++#define SHF_EXECINSTR 0x4 ++#define SHF_MERGE 0x10 ++#define SHF_STRINGS 0x20 ++#define SHF_INFO_LINK 0x40 ++#define SHF_LINK_ORDER 0x80 ++#define SHF_OS_NONCONFORMING 0x100 ++#define SHF_GROUP 0x200 ++#define SHF_TLS 0x400 ++#define SHF_MASKOS 0x0ff00000 ++#define SHF_MASKPROC 0xF0000000 ++ ++// Section group flags ++#define GRP_COMDAT 0x1 ++#define GRP_MASKOS 0x0ff00000 ++#define GRP_MASKPROC 0xf0000000 ++ ++// Symbol binding ++#define STB_LOCAL 0 ++#define STB_GLOBAL 1 ++#define STB_WEAK 2 ++#define STB_LOOS 10 ++#define STB_HIOS 12 ++#define STB_MULTIDEF 13 ++#define STB_LOPROC 13 ++#define STB_HIPROC 15 ++ ++// Note types ++#define NT_AMDGPU_METADATA 1 ++#define NT_AMD_AMDGPU_HSA_METADATA 10 ++#define NT_AMD_AMDGPU_ISA 11 ++#define NT_AMD_AMDGPU_PAL_METADATA 12 ++ ++// Symbol types ++#define STT_NOTYPE 0 ++#define STT_OBJECT 1 ++#define STT_FUNC 2 ++#define STT_SECTION 3 ++#define STT_FILE 4 ++#define STT_COMMON 5 ++#define STT_TLS 6 ++#define STT_LOOS 10 ++#define STT_AMDGPU_HSA_KERNEL 10 ++#define STT_HIOS 12 ++#define STT_LOPROC 13 ++#define STT_HIPROC 15 ++ ++// Symbol visibility ++#define STV_DEFAULT 0 ++#define STV_INTERNAL 1 ++#define STV_HIDDEN 2 ++#define STV_PROTECTED 3 ++ ++// Undefined name ++#define STN_UNDEF 0 ++ ++// Relocation types ++#define R_386_NONE 0 ++#define R_X86_64_NONE 0 ++#define R_AMDGPU_NONE 0 ++#define R_386_32 1 ++#define R_X86_64_64 1 ++#define R_AMDGPU_ABS32_LO 1 ++#define R_386_PC32 2 ++#define R_X86_64_PC32 2 ++#define R_AMDGPU_ABS32_HI 2 ++#define R_386_GOT32 3 ++#define R_X86_64_GOT32 3 ++#define R_AMDGPU_ABS64 3 ++#define R_386_PLT32 4 ++#define R_X86_64_PLT32 4 ++#define R_AMDGPU_REL32 4 ++#define R_386_COPY 5 ++#define R_X86_64_COPY 5 ++#define R_AMDGPU_REL64 5 ++#define R_386_GLOB_DAT 6 ++#define R_X86_64_GLOB_DAT 6 ++#define R_AMDGPU_ABS32 6 ++#define R_386_JMP_SLOT 7 ++#define R_X86_64_JUMP_SLOT 7 ++#define R_AMDGPU_GOTPCREL 7 ++#define R_386_RELATIVE 8 ++#define R_X86_64_RELATIVE 8 ++#define R_AMDGPU_GOTPCREL32_LO 8 ++#define R_386_GOTOFF 9 ++#define R_X86_64_GOTPCREL 9 ++#define R_AMDGPU_GOTPCREL32_HI 9 ++#define R_386_GOTPC 10 ++#define R_X86_64_32 10 ++#define R_AMDGPU_REL32_LO 10 ++#define R_386_32PLT 11 ++#define R_X86_64_32S 11 ++#define R_AMDGPU_REL32_HI 11 ++#define R_X86_64_16 12 ++#define R_X86_64_PC16 13 ++#define R_AMDGPU_RELATIVE64 13 ++#define R_386_TLS_TPOFF 14 ++#define R_X86_64_8 14 ++#define R_386_TLS_IE 15 ++#define R_X86_64_PC8 15 ++#define R_386_TLS_GOTIE 16 ++#define R_X86_64_DTPMOD64 16 ++#define R_386_TLS_LE 17 ++#define R_X86_64_DTPOFF64 17 ++#define R_386_TLS_GD 18 ++#define R_X86_64_TPOFF64 18 ++#define R_386_TLS_LDM 19 ++#define R_X86_64_TLSGD 19 ++#define R_386_16 20 ++#define R_X86_64_TLSLD 20 ++#define R_386_PC16 21 ++#define R_X86_64_DTPOFF32 21 ++#define R_386_8 22 ++#define R_X86_64_GOTTPOFF 22 ++#define R_386_PC8 23 ++#define R_X86_64_TPOFF32 23 ++#define R_386_TLS_GD_32 24 ++#define R_X86_64_PC64 24 ++#define R_386_TLS_GD_PUSH 25 ++#define R_X86_64_GOTOFF64 25 ++#define R_386_TLS_GD_CALL 26 ++#define R_X86_64_GOTPC32 26 ++#define R_386_TLS_GD_POP 27 ++#define R_X86_64_GOT64 27 ++#define R_386_TLS_LDM_32 28 ++#define R_X86_64_GOTPCREL64 28 ++#define R_386_TLS_LDM_PUSH 29 ++#define R_X86_64_GOTPC64 29 ++#define R_386_TLS_LDM_CALL 30 ++#define R_X86_64_GOTPLT64 30 ++#define R_386_TLS_LDM_POP 31 ++#define R_X86_64_PLTOFF64 31 ++#define R_386_TLS_LDO_32 32 ++#define R_386_TLS_IE_32 33 ++#define R_386_TLS_LE_32 34 ++#define R_X86_64_GOTPC32_TLSDESC 34 ++#define R_386_TLS_DTPMOD32 35 ++#define R_X86_64_TLSDESC_CALL 35 ++#define R_386_TLS_DTPOFF32 36 ++#define R_X86_64_TLSDESC 36 ++#define R_386_TLS_TPOFF32 37 ++#define R_X86_64_IRELATIVE 37 ++#define R_386_SIZE32 38 ++#define R_386_TLS_GOTDESC 39 ++#define R_386_TLS_DESC_CALL 40 ++#define R_386_TLS_DESC 41 ++#define R_386_IRELATIVE 42 ++#define R_386_GOT32X 43 ++#define R_X86_64_GNU_VTINHERIT 250 ++#define R_X86_64_GNU_VTENTRY 251 ++ ++// Segment types ++#define PT_NULL 0 ++#define PT_LOAD 1 ++#define PT_DYNAMIC 2 ++#define PT_INTERP 3 ++#define PT_NOTE 4 ++#define PT_SHLIB 5 ++#define PT_PHDR 6 ++#define PT_TLS 7 ++#define PT_LOOS 0x60000000 ++#define PT_HIOS 0x6fffffff ++#define PT_LOPROC 0x70000000 ++#define PT_HIPROC 0x7FFFFFFF ++ ++// Segment flags ++#define PF_X 1 // Execute ++#define PF_W 2 // Write ++#define PF_R 4 // Read ++#define PF_MASKOS 0x0ff00000 // Unspecified ++#define PF_MASKPROC 0xf0000000 // Unspecified ++ ++// Dynamic Array Tags ++#define DT_NULL 0 ++#define DT_NEEDED 1 ++#define DT_PLTRELSZ 2 ++#define DT_PLTGOT 3 ++#define DT_HASH 4 ++#define DT_STRTAB 5 ++#define DT_SYMTAB 6 ++#define DT_RELA 7 ++#define DT_RELASZ 8 ++#define DT_RELAENT 9 ++#define DT_STRSZ 10 ++#define DT_SYMENT 11 ++#define DT_INIT 12 ++#define DT_FINI 13 ++#define DT_SONAME 14 ++#define DT_RPATH 15 ++#define DT_SYMBOLIC 16 ++#define DT_REL 17 ++#define DT_RELSZ 18 ++#define DT_RELENT 19 ++#define DT_PLTREL 20 ++#define DT_DEBUG 21 ++#define DT_TEXTREL 22 ++#define DT_JMPREL 23 ++#define DT_BIND_NOW 24 ++#define DT_INIT_ARRAY 25 ++#define DT_FINI_ARRAY 26 ++#define DT_INIT_ARRAYSZ 27 ++#define DT_FINI_ARRAYSZ 28 ++#define DT_RUNPATH 29 ++#define DT_FLAGS 30 ++#define DT_ENCODING 32 ++#define DT_PREINIT_ARRAY 32 ++#define DT_PREINIT_ARRAYSZ 33 ++#define DT_MAXPOSTAGS 34 ++#define DT_LOOS 0x6000000D ++#define DT_HIOS 0x6ffff000 ++#define DT_LOPROC 0x70000000 ++#define DT_HIPROC 0x7FFFFFFF ++ ++// DT_FLAGS values ++#define DF_ORIGIN 0x1 ++#define DF_SYMBOLIC 0x2 ++#define DF_TEXTREL 0x4 ++#define DF_BIND_NOW 0x8 ++#define DF_STATIC_TLS 0x10 ++ ++// ELF file header ++struct Elf32_Ehdr ++{ ++ unsigned char e_ident[EI_NIDENT]; ++ Elf_Half e_type; ++ Elf_Half e_machine; ++ Elf_Word e_version; ++ Elf32_Addr e_entry; ++ Elf32_Off e_phoff; ++ Elf32_Off e_shoff; ++ Elf_Word e_flags; ++ Elf_Half e_ehsize; ++ Elf_Half e_phentsize; ++ Elf_Half e_phnum; ++ Elf_Half e_shentsize; ++ Elf_Half e_shnum; ++ Elf_Half e_shstrndx; ++}; ++ ++struct Elf64_Ehdr ++{ ++ unsigned char e_ident[EI_NIDENT]; ++ Elf_Half e_type; ++ Elf_Half e_machine; ++ Elf_Word e_version; ++ Elf64_Addr e_entry; ++ Elf64_Off e_phoff; ++ Elf64_Off e_shoff; ++ Elf_Word e_flags; ++ Elf_Half e_ehsize; ++ Elf_Half e_phentsize; ++ Elf_Half e_phnum; ++ Elf_Half e_shentsize; ++ Elf_Half e_shnum; ++ Elf_Half e_shstrndx; ++}; ++ ++// Section header ++struct Elf32_Shdr ++{ ++ Elf_Word sh_name; ++ Elf_Word sh_type; ++ Elf_Word sh_flags; ++ Elf32_Addr sh_addr; ++ Elf32_Off sh_offset; ++ Elf_Word sh_size; ++ Elf_Word sh_link; ++ Elf_Word sh_info; ++ Elf_Word sh_addralign; ++ Elf_Word sh_entsize; ++}; ++ ++struct Elf64_Shdr ++{ ++ Elf_Word sh_name; ++ Elf_Word sh_type; ++ Elf_Xword sh_flags; ++ Elf64_Addr sh_addr; ++ Elf64_Off sh_offset; ++ Elf_Xword sh_size; ++ Elf_Word sh_link; ++ Elf_Word sh_info; ++ Elf_Xword sh_addralign; ++ Elf_Xword sh_entsize; ++}; ++ ++// Segment header ++struct Elf32_Phdr ++{ ++ Elf_Word p_type; ++ Elf32_Off p_offset; ++ Elf32_Addr p_vaddr; ++ Elf32_Addr p_paddr; ++ Elf_Word p_filesz; ++ Elf_Word p_memsz; ++ Elf_Word p_flags; ++ Elf_Word p_align; ++}; ++ ++struct Elf64_Phdr ++{ ++ Elf_Word p_type; ++ Elf_Word p_flags; ++ Elf64_Off p_offset; ++ Elf64_Addr p_vaddr; ++ Elf64_Addr p_paddr; ++ Elf_Xword p_filesz; ++ Elf_Xword p_memsz; ++ Elf_Xword p_align; ++}; ++ ++// Symbol table entry ++struct Elf32_Sym ++{ ++ Elf_Word st_name; ++ Elf32_Addr st_value; ++ Elf_Word st_size; ++ unsigned char st_info; ++ unsigned char st_other; ++ Elf_Half st_shndx; ++}; ++ ++struct Elf64_Sym ++{ ++ Elf_Word st_name; ++ unsigned char st_info; ++ unsigned char st_other; ++ Elf_Half st_shndx; ++ Elf64_Addr st_value; ++ Elf_Xword st_size; ++}; ++ ++#define ELF_ST_BIND( i ) ( ( i ) >> 4 ) ++#define ELF_ST_TYPE( i ) ( (i)&0xf ) ++#define ELF_ST_INFO( b, t ) ( ( ( b ) << 4 ) + ( (t)&0xf ) ) ++ ++#define ELF_ST_VISIBILITY( o ) ( (o)&0x3 ) ++ ++// Relocation entries ++struct Elf32_Rel ++{ ++ Elf32_Addr r_offset; ++ Elf_Word r_info; ++}; ++ ++struct Elf32_Rela ++{ ++ Elf32_Addr r_offset; ++ Elf_Word r_info; ++ Elf_Sword r_addend; ++}; ++ ++struct Elf64_Rel ++{ ++ Elf64_Addr r_offset; ++ Elf_Xword r_info; ++}; ++ ++struct Elf64_Rela ++{ ++ Elf64_Addr r_offset; ++ Elf_Xword r_info; ++ Elf_Sxword r_addend; ++}; ++ ++#define ELF32_R_SYM( i ) ( ( i ) >> 8 ) ++#define ELF32_R_TYPE( i ) ( (unsigned char)( i ) ) ++#define ELF32_R_INFO( s, t ) ( ( ( s ) << 8 ) + (unsigned char)( t ) ) ++ ++#define ELF64_R_SYM( i ) ( ( i ) >> 32 ) ++#define ELF64_R_TYPE( i ) ( (i)&0xffffffffL ) ++#define ELF64_R_INFO( s, t ) \ ++ ( ( ( ( int64_t )( s ) ) << 32 ) + ( (t)&0xffffffffL ) ) ++ ++// Dynamic structure ++struct Elf32_Dyn ++{ ++ Elf_Sword d_tag; ++ union { ++ Elf_Word d_val; ++ Elf32_Addr d_ptr; ++ } d_un; ++}; ++ ++struct Elf64_Dyn ++{ ++ Elf_Sxword d_tag; ++ union { ++ Elf_Xword d_val; ++ Elf64_Addr d_ptr; ++ } d_un; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFTYPES_H ++ ++/*** End of inlined file: elf_types.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_version.hpp ***/ ++#define ELFIO_VERSION "3.8" ++ ++/*** End of inlined file: elfio_version.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_utils.hpp ***/ ++#ifndef ELFIO_UTILS_HPP ++#define ELFIO_UTILS_HPP ++ ++#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ ++ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } ++#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ ++ void set_##NAME( TYPE value ) \ ++ { \ ++ FIELD = value; \ ++ FIELD = ( *convertor )( FIELD ); \ ++ } ++#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ ++ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \ ++ void set_##NAME( TYPE value ) \ ++ { \ ++ FIELD = value; \ ++ FIELD = ( *convertor )( FIELD ); \ ++ } ++ ++#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0 ++ ++#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ ++ virtual void set_##NAME( TYPE value ) = 0 ++ ++#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ ++ virtual TYPE get_##NAME() const = 0; \ ++ virtual void set_##NAME( TYPE value ) = 0 ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++class endianess_convertor ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ endianess_convertor() { need_conversion = false; } ++ ++ //------------------------------------------------------------------------------ ++ void setup( unsigned char elf_file_encoding ) ++ { ++ need_conversion = ( elf_file_encoding != get_host_encoding() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint64_t operator()( uint64_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ( ( value & 0x00000000000000FFull ) << 56 ) | ++ ( ( value & 0x000000000000FF00ull ) << 40 ) | ++ ( ( value & 0x0000000000FF0000ull ) << 24 ) | ++ ( ( value & 0x00000000FF000000ull ) << 8 ) | ++ ( ( value & 0x000000FF00000000ull ) >> 8 ) | ++ ( ( value & 0x0000FF0000000000ull ) >> 24 ) | ++ ( ( value & 0x00FF000000000000ull ) >> 40 ) | ++ ( ( value & 0xFF00000000000000ull ) >> 56 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int64_t operator()( int64_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int64_t )( *this )( (uint64_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint32_t operator()( uint32_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ++ ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) | ++ ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int32_t operator()( int32_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int32_t )( *this )( (uint32_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint16_t operator()( uint16_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int16_t operator()( int16_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int16_t )( *this )( (uint16_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ int8_t operator()( int8_t value ) const { return value; } ++ ++ //------------------------------------------------------------------------------ ++ uint8_t operator()( uint8_t value ) const { return value; } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ unsigned char get_host_encoding() const ++ { ++ static const int tmp = 1; ++ if ( 1 == *(const char*)&tmp ) { ++ return ELFDATA2LSB; ++ } ++ else { ++ return ELFDATA2MSB; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ bool need_conversion; ++}; ++ ++//------------------------------------------------------------------------------ ++inline uint32_t elf_hash( const unsigned char* name ) ++{ ++ uint32_t h = 0, g; ++ while ( *name ) { ++ h = ( h << 4 ) + *name++; ++ g = h & 0xf0000000; ++ if ( g != 0 ) ++ h ^= g >> 24; ++ h &= ~g; ++ } ++ return h; ++} ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_UTILS_HPP ++ ++/*** End of inlined file: elfio_utils.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_header.hpp ***/ ++#ifndef ELF_HEADER_HPP ++#define ELF_HEADER_HPP ++ ++#include <iostream> ++ ++namespace ELFIO { ++ ++class elf_header ++{ ++ public: ++ virtual ~elf_header(){}; ++ virtual bool load( std::istream& stream ) = 0; ++ virtual bool save( std::ostream& stream ) const = 0; ++ ++ // ELF header functions ++ ELFIO_GET_ACCESS_DECL( unsigned char, class ); ++ ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); ++ ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); ++ ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); ++ ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); ++ ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); ++}; ++ ++template <class T> struct elf_header_impl_types; ++template <> struct elf_header_impl_types<Elf32_Ehdr> ++{ ++ typedef Elf32_Phdr Phdr_type; ++ typedef Elf32_Shdr Shdr_type; ++ static const unsigned char file_class = ELFCLASS32; ++}; ++template <> struct elf_header_impl_types<Elf64_Ehdr> ++{ ++ typedef Elf64_Phdr Phdr_type; ++ typedef Elf64_Shdr Shdr_type; ++ static const unsigned char file_class = ELFCLASS64; ++}; ++ ++template <class T> class elf_header_impl : public elf_header ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ elf_header_impl( endianess_convertor* convertor_, unsigned char encoding ) ++ { ++ convertor = convertor_; ++ ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ ++ header.e_ident[EI_MAG0] = ELFMAG0; ++ header.e_ident[EI_MAG1] = ELFMAG1; ++ header.e_ident[EI_MAG2] = ELFMAG2; ++ header.e_ident[EI_MAG3] = ELFMAG3; ++ header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class; ++ header.e_ident[EI_DATA] = encoding; ++ header.e_ident[EI_VERSION] = EV_CURRENT; ++ header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); ++ header.e_ehsize = ( sizeof( header ) ); ++ header.e_ehsize = ( *convertor )( header.e_ehsize ); ++ header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); ++ header.e_phentsize = ++ sizeof( typename elf_header_impl_types<T>::Phdr_type ); ++ header.e_shentsize = ++ sizeof( typename elf_header_impl_types<T>::Shdr_type ); ++ header.e_phentsize = ( *convertor )( header.e_phentsize ); ++ header.e_shentsize = ( *convertor )( header.e_shentsize ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( std::istream& stream ) ++ { ++ stream.seekg( 0 ); ++ stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); ++ ++ return ( stream.gcount() == sizeof( header ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( std::ostream& stream ) const ++ { ++ stream.seekp( 0 ); ++ stream.write( reinterpret_cast<const char*>( &header ), ++ sizeof( header ) ); ++ ++ return stream.good(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ // ELF header functions ++ ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); ++ ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); ++ ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); ++ ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); ++ ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); ++ ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); ++ ++ ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); ++ ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); ++ ELFIO_GET_SET_ACCESS( unsigned char, ++ abi_version, ++ header.e_ident[EI_ABIVERSION] ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); ++ ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); ++ ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); ++ ++ private: ++ T header; ++ endianess_convertor* convertor; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELF_HEADER_HPP ++ ++/*** End of inlined file: elfio_header.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_section.hpp ***/ ++#ifndef ELFIO_SECTION_HPP ++#define ELFIO_SECTION_HPP ++ ++#include <string> ++#include <iostream> ++#include <new> ++ ++namespace ELFIO { ++ ++class section ++{ ++ friend class elfio; ++ ++ public: ++ virtual ~section(){}; ++ ++ ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ++ ELFIO_GET_SET_ACCESS_DECL( std::string, name ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); ++ ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); ++ ++ virtual const char* get_data() const = 0; ++ virtual void set_data( const char* pData, Elf_Word size ) = 0; ++ virtual void set_data( const std::string& data ) = 0; ++ virtual void append_data( const char* pData, Elf_Word size ) = 0; ++ virtual void append_data( const std::string& data ) = 0; ++ virtual size_t get_stream_size() const = 0; ++ virtual void set_stream_size( size_t value ) = 0; ++ ++ protected: ++ ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ++ ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ++ ++ virtual void load( std::istream& stream, std::streampos header_offset ) = 0; ++ virtual void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) = 0; ++ virtual bool is_address_initialized() const = 0; ++}; ++ ++template <class T> class section_impl : public section ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ section_impl( const endianess_convertor* convertor_ ) ++ : convertor( convertor_ ) ++ { ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ is_address_set = false; ++ data = 0; ++ data_size = 0; ++ index = 0; ++ stream_size = 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ ~section_impl() { delete[] data; } ++ ++ //------------------------------------------------------------------------------ ++ // Section info functions ++ ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); ++ ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr ); ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_index() const { return index; } ++ ++ //------------------------------------------------------------------------------ ++ std::string get_name() const { return name; } ++ ++ //------------------------------------------------------------------------------ ++ void set_name( std::string name_ ) { name = name_; } ++ ++ //------------------------------------------------------------------------------ ++ void set_address( Elf64_Addr value ) ++ { ++ header.sh_addr = value; ++ header.sh_addr = ( *convertor )( header.sh_addr ); ++ is_address_set = true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_address_initialized() const { return is_address_set; } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_data() const { return data; } ++ ++ //------------------------------------------------------------------------------ ++ void set_data( const char* raw_data, Elf_Word size ) ++ { ++ if ( get_type() != SHT_NOBITS ) { ++ delete[] data; ++ data = new ( std::nothrow ) char[size]; ++ if ( 0 != data && 0 != raw_data ) { ++ data_size = size; ++ std::copy( raw_data, raw_data + size, data ); ++ } ++ else { ++ data_size = 0; ++ } ++ } ++ ++ set_size( data_size ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void set_data( const std::string& str_data ) ++ { ++ return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void append_data( const char* raw_data, Elf_Word size ) ++ { ++ if ( get_type() != SHT_NOBITS ) { ++ if ( get_size() + size < data_size ) { ++ std::copy( raw_data, raw_data + size, data + get_size() ); ++ } ++ else { ++ data_size = 2 * ( data_size + size ); ++ char* new_data = new ( std::nothrow ) char[data_size]; ++ ++ if ( 0 != new_data ) { ++ std::copy( data, data + get_size(), new_data ); ++ std::copy( raw_data, raw_data + size, ++ new_data + get_size() ); ++ delete[] data; ++ data = new_data; ++ } ++ else { ++ size = 0; ++ } ++ } ++ set_size( get_size() + size ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void append_data( const std::string& str_data ) ++ { ++ return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ protected: ++ //------------------------------------------------------------------------------ ++ ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); ++ ++ //------------------------------------------------------------------------------ ++ void set_index( Elf_Half value ) { index = value; } ++ ++ //------------------------------------------------------------------------------ ++ void load( std::istream& stream, std::streampos header_offset ) ++ { ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ ++ stream.seekg( 0, stream.end ); ++ set_stream_size( stream.tellg() ); ++ ++ stream.seekg( header_offset ); ++ stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); ++ ++ Elf_Xword size = get_size(); ++ if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && ++ size < get_stream_size() ) { ++ data = new ( std::nothrow ) char[size + 1]; ++ ++ if ( ( 0 != size ) && ( 0 != data ) ) { ++ stream.seekg( ( *convertor )( header.sh_offset ) ); ++ stream.read( data, size ); ++ data[size] = 0; // Ensure data is ended with 0 to avoid oob read ++ data_size = size; ++ } ++ else { ++ data_size = 0; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) ++ { ++ if ( 0 != get_index() ) { ++ header.sh_offset = data_offset; ++ header.sh_offset = ( *convertor )( header.sh_offset ); ++ } ++ ++ save_header( stream, header_offset ); ++ if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && ++ get_size() != 0 && data != 0 ) { ++ save_data( stream, data_offset ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void save_header( std::ostream& stream, std::streampos header_offset ) const ++ { ++ stream.seekp( header_offset ); ++ stream.write( reinterpret_cast<const char*>( &header ), ++ sizeof( header ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save_data( std::ostream& stream, std::streampos data_offset ) const ++ { ++ stream.seekp( data_offset ); ++ stream.write( get_data(), get_size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ size_t get_stream_size() const { return stream_size; } ++ ++ //------------------------------------------------------------------------------ ++ void set_stream_size( size_t value ) { stream_size = value; } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ T header; ++ Elf_Half index; ++ std::string name; ++ char* data; ++ Elf_Word data_size; ++ const endianess_convertor* convertor; ++ bool is_address_set; ++ size_t stream_size; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SECTION_HPP ++ ++/*** End of inlined file: elfio_section.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_segment.hpp ***/ ++#ifndef ELFIO_SEGMENT_HPP ++#define ELFIO_SEGMENT_HPP ++ ++#include <iostream> ++#include <vector> ++#include <new> ++ ++namespace ELFIO { ++ ++class segment ++{ ++ friend class elfio; ++ ++ public: ++ virtual ~segment(){}; ++ ++ ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); ++ ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); ++ ++ virtual const char* get_data() const = 0; ++ ++ virtual Elf_Half add_section_index( Elf_Half index, ++ Elf_Xword addr_align ) = 0; ++ virtual Elf_Half get_sections_num() const = 0; ++ virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; ++ virtual bool is_offset_initialized() const = 0; ++ ++ protected: ++ ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ++ ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ++ ++ virtual const std::vector<Elf_Half>& get_sections() const = 0; ++ virtual void load( std::istream& stream, std::streampos header_offset ) = 0; ++ virtual void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) = 0; ++}; ++ ++//------------------------------------------------------------------------------ ++template <class T> class segment_impl : public segment ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ segment_impl( endianess_convertor* convertor_ ) ++ : stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) ++ { ++ is_offset_set = false; ++ std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ virtual ~segment_impl() { delete[] data; } ++ ++ //------------------------------------------------------------------------------ ++ // Section info functions ++ ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); ++ ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); ++ size_t stream_size; ++ ++ //------------------------------------------------------------------------------ ++ size_t get_stream_size() const { return stream_size; } ++ ++ //------------------------------------------------------------------------------ ++ void set_stream_size( size_t value ) { stream_size = value; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_index() const { return index; } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_data() const { return data; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) ++ { ++ sections.push_back( sec_index ); ++ if ( addr_align > get_align() ) { ++ set_align( addr_align ); ++ } ++ ++ return (Elf_Half)sections.size(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_section_index_at( Elf_Half num ) const ++ { ++ if ( num < sections.size() ) { ++ return sections[num]; ++ } ++ ++ return Elf_Half( -1 ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ protected: ++ //------------------------------------------------------------------------------ ++ ++ //------------------------------------------------------------------------------ ++ void set_offset( Elf64_Off value ) ++ { ++ ph.p_offset = value; ++ ph.p_offset = ( *convertor )( ph.p_offset ); ++ is_offset_set = true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_offset_initialized() const { return is_offset_set; } ++ ++ //------------------------------------------------------------------------------ ++ const std::vector<Elf_Half>& get_sections() const { return sections; } ++ ++ //------------------------------------------------------------------------------ ++ void set_index( Elf_Half value ) { index = value; } ++ ++ //------------------------------------------------------------------------------ ++ void load( std::istream& stream, std::streampos header_offset ) ++ { ++ ++ stream.seekg( 0, stream.end ); ++ set_stream_size( stream.tellg() ); ++ ++ stream.seekg( header_offset ); ++ stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) ); ++ is_offset_set = true; ++ ++ if ( PT_NULL != get_type() && 0 != get_file_size() ) { ++ stream.seekg( ( *convertor )( ph.p_offset ) ); ++ Elf_Xword size = get_file_size(); ++ ++ if ( size > get_stream_size() ) { ++ data = 0; ++ } ++ else { ++ data = new (std::nothrow) char[size + 1]; ++ ++ if ( 0 != data ) { ++ stream.read( data, size ); ++ data[size] = 0; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) ++ { ++ ph.p_offset = data_offset; ++ ph.p_offset = ( *convertor )( ph.p_offset ); ++ stream.seekp( header_offset ); ++ stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ T ph; ++ Elf_Half index; ++ char* data; ++ std::vector<Elf_Half> sections; ++ endianess_convertor* convertor; ++ bool is_offset_set; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SEGMENT_HPP ++ ++/*** End of inlined file: elfio_segment.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_strings.hpp ***/ ++#ifndef ELFIO_STRINGS_HPP ++#define ELFIO_STRINGS_HPP ++ ++#include <cstdlib> ++#include <cstring> ++#include <string> ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class string_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ string_section_accessor_template( S* section_ ) : string_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_string( Elf_Word index ) const ++ { ++ if ( string_section ) { ++ if ( index < string_section->get_size() ) { ++ const char* data = string_section->get_data(); ++ if ( 0 != data ) { ++ return data + index; ++ } ++ } ++ } ++ ++ return 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_string( const char* str ) ++ { ++ Elf_Word current_position = 0; ++ ++ if ( string_section ) { ++ // Strings are addeded to the end of the current section data ++ current_position = (Elf_Word)string_section->get_size(); ++ ++ if ( current_position == 0 ) { ++ char empty_string = '\0'; ++ string_section->append_data( &empty_string, 1 ); ++ current_position++; ++ } ++ string_section->append_data( str, ++ (Elf_Word)std::strlen( str ) + 1 ); ++ } ++ ++ return current_position; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_string( const std::string& str ) ++ { ++ return add_string( str.c_str() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ S* string_section; ++}; ++ ++using string_section_accessor = string_section_accessor_template<section>; ++using const_string_section_accessor = ++ string_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_STRINGS_HPP ++ ++/*** End of inlined file: elfio_strings.hpp ***/ ++ ++#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \ ++ TYPE get_##FNAME() const { return header ? ( header->get_##FNAME() ) : 0; } ++ ++#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \ ++ TYPE get_##FNAME() const \ ++ { \ ++ return header ? ( header->get_##FNAME() ) : 0; \ ++ } \ ++ void set_##FNAME( TYPE val ) \ ++ { \ ++ if ( header ) { \ ++ header->set_##FNAME( val ); \ ++ } \ ++ } ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++class elfio ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ elfio() : sections( this ), segments( this ) ++ { ++ header = 0; ++ current_file_pos = 0; ++ create( ELFCLASS32, ELFDATA2LSB ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ ~elfio() { clean(); } ++ ++ //------------------------------------------------------------------------------ ++ void create( unsigned char file_class, unsigned char encoding ) ++ { ++ clean(); ++ convertor.setup( encoding ); ++ header = create_header( file_class, encoding ); ++ create_mandatory_sections(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( const std::string& file_name ) ++ { ++ std::ifstream stream; ++ stream.open( file_name.c_str(), std::ios::in | std::ios::binary ); ++ if ( !stream ) { ++ return false; ++ } ++ ++ return load( stream ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( std::istream& stream ) ++ { ++ clean(); ++ ++ unsigned char e_ident[EI_NIDENT]; ++ // Read ELF file signature ++ stream.read( reinterpret_cast<char*>( &e_ident ), sizeof( e_ident ) ); ++ ++ // Is it ELF file? ++ if ( stream.gcount() != sizeof( e_ident ) || ++ e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || ++ e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 ) { ++ return false; ++ } ++ ++ if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) && ++ ( e_ident[EI_CLASS] != ELFCLASS32 ) ) { ++ return false; ++ } ++ ++ convertor.setup( e_ident[EI_DATA] ); ++ header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] ); ++ if ( 0 == header ) { ++ return false; ++ } ++ if ( !header->load( stream ) ) { ++ return false; ++ } ++ ++ load_sections( stream ); ++ bool is_still_good = load_segments( stream ); ++ return is_still_good; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( const std::string& file_name ) ++ { ++ std::ofstream stream; ++ stream.open( file_name.c_str(), std::ios::out | std::ios::binary ); ++ if ( !stream ) { ++ return false; ++ } ++ ++ return save( stream ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( std::ostream& stream ) ++ { ++ if ( !stream || !header ) { ++ return false; ++ } ++ ++ bool is_still_good = true; ++ // Define layout specific header fields ++ // The position of the segment table is fixed after the header. ++ // The position of the section table is variable and needs to be fixed ++ // before saving. ++ header->set_segments_num( segments.size() ); ++ header->set_segments_offset( segments.size() ? header->get_header_size() ++ : 0 ); ++ header->set_sections_num( sections.size() ); ++ header->set_sections_offset( 0 ); ++ ++ // Layout the first section right after the segment table ++ current_file_pos = header->get_header_size() + ++ header->get_segment_entry_size() * ++ (Elf_Xword)header->get_segments_num(); ++ ++ calc_segment_alignment(); ++ ++ is_still_good = layout_segments_and_their_sections(); ++ is_still_good = is_still_good && layout_sections_without_segments(); ++ is_still_good = is_still_good && layout_section_table(); ++ ++ is_still_good = is_still_good && save_header( stream ); ++ is_still_good = is_still_good && save_sections( stream ); ++ is_still_good = is_still_good && save_segments( stream ); ++ ++ return is_still_good; ++ } ++ ++ //------------------------------------------------------------------------------ ++ // ELF header access functions ++ ELFIO_HEADER_ACCESS_GET( unsigned char, class ); ++ ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version ); ++ ELFIO_HEADER_ACCESS_GET( unsigned char, encoding ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Word, version ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size ); ++ ++ ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi ); ++ ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); ++ ++ //------------------------------------------------------------------------------ ++ const endianess_convertor& get_convertor() const { return convertor; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_default_entry_size( Elf_Word section_type ) const ++ { ++ switch ( section_type ) { ++ case SHT_RELA: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Rela ); ++ } ++ else { ++ return sizeof( Elf32_Rela ); ++ } ++ case SHT_REL: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Rel ); ++ } ++ else { ++ return sizeof( Elf32_Rel ); ++ } ++ case SHT_SYMTAB: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Sym ); ++ } ++ else { ++ return sizeof( Elf32_Sym ); ++ } ++ case SHT_DYNAMIC: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Dyn ); ++ } ++ else { ++ return sizeof( Elf32_Dyn ); ++ } ++ default: ++ return 0; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ bool is_offset_in_section( Elf64_Off offset, const section* sec ) const ++ { ++ return ( offset >= sec->get_offset() ) && ++ ( offset < ( sec->get_offset() + sec->get_size() ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ public: ++ //! returns an empty string if no problems are detected, ++ //! or a string containing an error message if problems are found ++ std::string validate() const ++ { ++ ++ // check for overlapping sections in the file ++ for ( int i = 0; i < sections.size(); ++i ) { ++ for ( int j = i + 1; j < sections.size(); ++j ) { ++ const section* a = sections[i]; ++ const section* b = sections[j]; ++ if ( !( a->get_type() & SHT_NOBITS ) && ++ !( b->get_type() & SHT_NOBITS ) && ( a->get_size() > 0 ) && ++ ( b->get_size() > 0 ) && ( a->get_offset() > 0 ) && ++ ( b->get_offset() > 0 ) ) { ++ if ( is_offset_in_section( a->get_offset(), b ) || ++ is_offset_in_section( ++ a->get_offset() + a->get_size() - 1, b ) || ++ is_offset_in_section( b->get_offset(), a ) || ++ is_offset_in_section( ++ b->get_offset() + b->get_size() - 1, a ) ) { ++ return "Sections " + a->get_name() + " and " + ++ b->get_name() + " overlap in file"; ++ } ++ } ++ } ++ } ++ ++ // more checks to be added here... ++ ++ return ""; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void clean() ++ { ++ delete header; ++ header = 0; ++ ++ std::vector<section*>::const_iterator it; ++ for ( it = sections_.begin(); it != sections_.end(); ++it ) { ++ delete *it; ++ } ++ sections_.clear(); ++ ++ std::vector<segment*>::const_iterator it1; ++ for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) { ++ delete *it1; ++ } ++ segments_.clear(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ elf_header* create_header( unsigned char file_class, ++ unsigned char encoding ) ++ { ++ elf_header* new_header = 0; ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_header = ++ new elf_header_impl<Elf64_Ehdr>( &convertor, encoding ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_header = ++ new elf_header_impl<Elf32_Ehdr>( &convertor, encoding ); ++ } ++ else { ++ return 0; ++ } ++ ++ return new_header; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* create_section() ++ { ++ section* new_section; ++ unsigned char file_class = get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_section = new section_impl<Elf64_Shdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_section = new section_impl<Elf32_Shdr>( &convertor ); ++ } ++ else { ++ return 0; ++ } ++ ++ new_section->set_index( (Elf_Half)sections_.size() ); ++ sections_.push_back( new_section ); ++ ++ return new_section; ++ } ++ ++ //------------------------------------------------------------------------------ ++ segment* create_segment() ++ { ++ segment* new_segment; ++ unsigned char file_class = header->get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_segment = new segment_impl<Elf64_Phdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_segment = new segment_impl<Elf32_Phdr>( &convertor ); ++ } ++ else { ++ return 0; ++ } ++ ++ new_segment->set_index( (Elf_Half)segments_.size() ); ++ segments_.push_back( new_segment ); ++ ++ return new_segment; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void create_mandatory_sections() ++ { ++ // Create null section without calling to 'add_section' as no string ++ // section containing section names exists yet ++ section* sec0 = create_section(); ++ sec0->set_index( 0 ); ++ sec0->set_name( "" ); ++ sec0->set_name_string_offset( 0 ); ++ ++ set_section_name_str_index( 1 ); ++ section* shstrtab = sections.add( ".shstrtab" ); ++ shstrtab->set_type( SHT_STRTAB ); ++ shstrtab->set_addr_align( 1 ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half load_sections( std::istream& stream ) ++ { ++ Elf_Half entry_size = header->get_section_entry_size(); ++ Elf_Half num = header->get_sections_num(); ++ Elf64_Off offset = header->get_sections_offset(); ++ ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ section* sec = create_section(); ++ sec->load( stream, (std::streamoff)offset + ++ (std::streampos)i * entry_size ); ++ sec->set_index( i ); ++ // To mark that the section is not permitted to reassign address ++ // during layout calculation ++ sec->set_address( sec->get_address() ); ++ } ++ ++ Elf_Half shstrndx = get_section_name_str_index(); ++ ++ if ( SHN_UNDEF != shstrndx ) { ++ string_section_accessor str_reader( sections[shstrndx] ); ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ Elf_Word section_offset = sections[i]->get_name_string_offset(); ++ const char* p = str_reader.get_string( section_offset ); ++ if ( p != 0 ) { ++ sections[i]->set_name( p ); ++ } ++ } ++ } ++ ++ return num; ++ } ++ ++ //------------------------------------------------------------------------------ ++ //! Checks whether the addresses of the section entirely fall within the given segment. ++ //! It doesn't matter if the addresses are memory addresses, or file offsets, ++ //! they just need to be in the same address space ++ bool is_sect_in_seg( Elf64_Off sect_begin, ++ Elf_Xword sect_size, ++ Elf64_Off seg_begin, ++ Elf64_Off seg_end ) ++ { ++ return ( seg_begin <= sect_begin ) && ++ ( sect_begin + sect_size <= seg_end ) && ++ ( sect_begin < ++ seg_end ); // this is important criteria when sect_size == 0 ++ // Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11) ++ // sect_begin=12, sect_size=0 -> shall return false! ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load_segments( std::istream& stream ) ++ { ++ Elf_Half entry_size = header->get_segment_entry_size(); ++ Elf_Half num = header->get_segments_num(); ++ Elf64_Off offset = header->get_segments_offset(); ++ ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ segment* seg; ++ unsigned char file_class = header->get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ seg = new segment_impl<Elf64_Phdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ seg = new segment_impl<Elf32_Phdr>( &convertor ); ++ } ++ else { ++ return false; ++ } ++ ++ seg->load( stream, (std::streamoff)offset + ++ (std::streampos)i * entry_size ); ++ seg->set_index( i ); ++ ++ // Add sections to the segments (similar to readelfs algorithm) ++ Elf64_Off segBaseOffset = seg->get_offset(); ++ Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size(); ++ Elf64_Off segVBaseAddr = seg->get_virtual_address(); ++ Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size(); ++ for ( Elf_Half j = 0; j < sections.size(); ++j ) { ++ const section* psec = sections[j]; ++ ++ // SHF_ALLOC sections are matched based on the virtual address ++ // otherwise the file offset is matched ++ if ( ( psec->get_flags() & SHF_ALLOC ) ++ ? is_sect_in_seg( psec->get_address(), ++ psec->get_size(), segVBaseAddr, ++ segVEndAddr ) ++ : is_sect_in_seg( psec->get_offset(), psec->get_size(), ++ segBaseOffset, segEndOffset ) ) { ++ // Alignment of segment shall not be updated, to preserve original value ++ // It will be re-calculated on saving. ++ seg->add_section_index( psec->get_index(), 0 ); ++ } ++ } ++ ++ // Add section into the segments' container ++ segments_.push_back( seg ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save_header( std::ostream& stream ) { return header->save( stream ); } ++ ++ //------------------------------------------------------------------------------ ++ bool save_sections( std::ostream& stream ) ++ { ++ for ( unsigned int i = 0; i < sections_.size(); ++i ) { ++ section* sec = sections_.at( i ); ++ ++ std::streampos headerPosition = ++ (std::streamoff)header->get_sections_offset() + ++ (std::streampos)header->get_section_entry_size() * ++ sec->get_index(); ++ ++ sec->save( stream, headerPosition, sec->get_offset() ); ++ } ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save_segments( std::ostream& stream ) ++ { ++ for ( unsigned int i = 0; i < segments_.size(); ++i ) { ++ segment* seg = segments_.at( i ); ++ ++ std::streampos headerPosition = ++ header->get_segments_offset() + ++ (std::streampos)header->get_segment_entry_size() * ++ seg->get_index(); ++ ++ seg->save( stream, headerPosition, seg->get_offset() ); ++ } ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_section_without_segment( unsigned int section_index ) ++ { ++ bool found = false; ++ ++ for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) { ++ for ( unsigned int k = 0; ++ !found && ( k < segments[j]->get_sections_num() ); ++k ) { ++ found = segments[j]->get_section_index_at( k ) == section_index; ++ } ++ } ++ ++ return !found; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_subsequence_of( segment* seg1, segment* seg2 ) ++ { ++ // Return 'true' if sections of seg1 are a subset of sections in seg2 ++ const std::vector<Elf_Half>& sections1 = seg1->get_sections(); ++ const std::vector<Elf_Half>& sections2 = seg2->get_sections(); ++ ++ bool found = false; ++ if ( sections1.size() < sections2.size() ) { ++ found = std::includes( sections2.begin(), sections2.end(), ++ sections1.begin(), sections1.end() ); ++ } ++ ++ return found; ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*> get_ordered_segments() ++ { ++ std::vector<segment*> res; ++ std::deque<segment*> worklist; ++ ++ res.reserve( segments.size() ); ++ std::copy( segments_.begin(), segments_.end(), ++ std::back_inserter( worklist ) ); ++ ++ // Bring the segments which start at address 0 to the front ++ size_t nextSlot = 0; ++ for ( size_t i = 0; i < worklist.size(); ++i ) { ++ if ( i != nextSlot && worklist[i]->is_offset_initialized() && ++ worklist[i]->get_offset() == 0 ) { ++ if ( worklist[nextSlot]->get_offset() == 0 ) { ++ ++nextSlot; ++ } ++ std::swap( worklist[i], worklist[nextSlot] ); ++ ++nextSlot; ++ } ++ } ++ ++ while ( !worklist.empty() ) { ++ segment* seg = worklist.front(); ++ worklist.pop_front(); ++ ++ size_t i = 0; ++ for ( ; i < worklist.size(); ++i ) { ++ if ( is_subsequence_of( seg, worklist[i] ) ) { ++ break; ++ } ++ } ++ ++ if ( i < worklist.size() ) ++ worklist.push_back( seg ); ++ else ++ res.push_back( seg ); ++ } ++ ++ return res; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_sections_without_segments() ++ { ++ for ( unsigned int i = 0; i < sections_.size(); ++i ) { ++ if ( is_section_without_segment( i ) ) { ++ section* sec = sections_[i]; ++ ++ Elf_Xword section_align = sec->get_addr_align(); ++ if ( section_align > 1 && ++ current_file_pos % section_align != 0 ) { ++ current_file_pos += ++ section_align - current_file_pos % section_align; ++ } ++ ++ if ( 0 != sec->get_index() ) ++ sec->set_offset( current_file_pos ); ++ ++ if ( SHT_NOBITS != sec->get_type() && ++ SHT_NULL != sec->get_type() ) { ++ current_file_pos += sec->get_size(); ++ } ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void calc_segment_alignment() ++ { ++ for ( std::vector<segment*>::iterator s = segments_.begin(); ++ s != segments_.end(); ++s ) { ++ segment* seg = *s; ++ for ( int i = 0; i < seg->get_sections_num(); ++i ) { ++ section* sect = sections_[seg->get_section_index_at( i )]; ++ if ( sect->get_addr_align() > seg->get_align() ) { ++ seg->set_align( sect->get_addr_align() ); ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_segments_and_their_sections() ++ { ++ std::vector<segment*> worklist; ++ std::vector<bool> section_generated( sections.size(), false ); ++ ++ // Get segments in a order in where segments which contain a ++ // sub sequence of other segments are located at the end ++ worklist = get_ordered_segments(); ++ ++ for ( unsigned int i = 0; i < worklist.size(); ++i ) { ++ Elf_Xword segment_memory = 0; ++ Elf_Xword segment_filesize = 0; ++ Elf_Xword seg_start_pos = current_file_pos; ++ segment* seg = worklist[i]; ++ ++ // Special case: PHDR segment ++ // This segment contains the program headers but no sections ++ if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) { ++ seg_start_pos = header->get_segments_offset(); ++ segment_memory = segment_filesize = ++ header->get_segment_entry_size() * ++ (Elf_Xword)header->get_segments_num(); ++ } ++ // Special case: ++ else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) { ++ seg_start_pos = 0; ++ if ( seg->get_sections_num() ) { ++ segment_memory = segment_filesize = current_file_pos; ++ } ++ } ++ // New segments with not generated sections ++ // have to be aligned ++ else if ( seg->get_sections_num() && ++ !section_generated[seg->get_section_index_at( 0 )] ) { ++ Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1; ++ Elf64_Off cur_page_alignment = current_file_pos % align; ++ Elf64_Off req_page_alignment = ++ seg->get_virtual_address() % align; ++ Elf64_Off error = req_page_alignment - cur_page_alignment; ++ ++ current_file_pos += ( seg->get_align() + error ) % align; ++ seg_start_pos = current_file_pos; ++ } ++ else if ( seg->get_sections_num() ) { ++ seg_start_pos = ++ sections[seg->get_section_index_at( 0 )]->get_offset(); ++ } ++ ++ // Write segment's data ++ for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) { ++ Elf_Half index = seg->get_section_index_at( j ); ++ ++ section* sec = sections[index]; ++ ++ // The NULL section is always generated ++ if ( SHT_NULL == sec->get_type() ) { ++ section_generated[index] = true; ++ continue; ++ } ++ ++ Elf_Xword secAlign = 0; ++ // Fix up the alignment ++ if ( !section_generated[index] && ++ sec->is_address_initialized() && ++ SHT_NOBITS != sec->get_type() && ++ SHT_NULL != sec->get_type() && 0 != sec->get_size() ) { ++ // Align the sections based on the virtual addresses ++ // when possible (this is what matters for execution) ++ Elf64_Off req_offset = ++ sec->get_address() - seg->get_virtual_address(); ++ Elf64_Off cur_offset = current_file_pos - seg_start_pos; ++ if ( req_offset < cur_offset ) { ++ // something has gone awfully wrong, abort! ++ // secAlign would turn out negative, seeking backwards and overwriting previous data ++ return false; ++ } ++ secAlign = req_offset - cur_offset; ++ } ++ else if ( !section_generated[index] && ++ !sec->is_address_initialized() ) { ++ // If no address has been specified then only the section ++ // alignment constraint has to be matched ++ Elf_Xword align = sec->get_addr_align(); ++ if ( align == 0 ) { ++ align = 1; ++ } ++ Elf64_Off error = current_file_pos % align; ++ secAlign = ( align - error ) % align; ++ } ++ else if ( section_generated[index] ) { ++ // Alignment for already generated sections ++ secAlign = ++ sec->get_offset() - seg_start_pos - segment_filesize; ++ } ++ ++ // Determine the segment file and memory sizes ++ // Special case .tbss section (NOBITS) in non TLS segment ++ if ( ( sec->get_flags() & SHF_ALLOC ) && ++ !( ( sec->get_flags() & SHF_TLS ) && ++ ( seg->get_type() != PT_TLS ) && ++ ( SHT_NOBITS == sec->get_type() ) ) ) ++ segment_memory += sec->get_size() + secAlign; ++ ++ if ( SHT_NOBITS != sec->get_type() ) ++ segment_filesize += sec->get_size() + secAlign; ++ ++ // Nothing to be done when generating nested segments ++ if ( section_generated[index] ) { ++ continue; ++ } ++ ++ current_file_pos += secAlign; ++ ++ // Set the section addresses when missing ++ if ( !sec->is_address_initialized() ) ++ sec->set_address( seg->get_virtual_address() + ++ current_file_pos - seg_start_pos ); ++ ++ if ( 0 != sec->get_index() ) ++ sec->set_offset( current_file_pos ); ++ ++ if ( SHT_NOBITS != sec->get_type() ) ++ current_file_pos += sec->get_size(); ++ ++ section_generated[index] = true; ++ } ++ ++ seg->set_file_size( segment_filesize ); ++ ++ // If we already have a memory size from loading an elf file (value > 0), ++ // it must not shrink! ++ // Memory size may be bigger than file size and it is the loader's job to do something ++ // with the surplus bytes in memory, like initializing them with a defined value. ++ if ( seg->get_memory_size() < segment_memory ) { ++ seg->set_memory_size( segment_memory ); ++ } ++ ++ seg->set_offset( seg_start_pos ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_section_table() ++ { ++ // Simply place the section table at the end for now ++ Elf64_Off alignmentError = current_file_pos % 4; ++ current_file_pos += ( 4 - alignmentError ) % 4; ++ header->set_sections_offset( current_file_pos ); ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ public: ++ friend class Sections; ++ class Sections ++ { ++ public: ++ //------------------------------------------------------------------------------ ++ Sections( elfio* parent_ ) : parent( parent_ ) {} ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half size() const { return (Elf_Half)parent->sections_.size(); } ++ ++ //------------------------------------------------------------------------------ ++ section* operator[]( unsigned int index ) const ++ { ++ section* sec = 0; ++ ++ if ( index < parent->sections_.size() ) { ++ sec = parent->sections_[index]; ++ } ++ ++ return sec; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* operator[]( const std::string& name ) const ++ { ++ section* sec = 0; ++ ++ std::vector<section*>::const_iterator it; ++ for ( it = parent->sections_.begin(); it != parent->sections_.end(); ++ ++it ) { ++ if ( ( *it )->get_name() == name ) { ++ sec = *it; ++ break; ++ } ++ } ++ ++ return sec; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* add( const std::string& name ) ++ { ++ section* new_section = parent->create_section(); ++ new_section->set_name( name ); ++ ++ Elf_Half str_index = parent->get_section_name_str_index(); ++ section* string_table( parent->sections_[str_index] ); ++ string_section_accessor str_writer( string_table ); ++ Elf_Word pos = str_writer.add_string( name ); ++ new_section->set_name_string_offset( pos ); ++ ++ return new_section; ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::iterator begin() ++ { ++ return parent->sections_.begin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::iterator end() ++ { ++ return parent->sections_.end(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::const_iterator begin() const ++ { ++ return parent->sections_.cbegin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::const_iterator end() const ++ { ++ return parent->sections_.cend(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elfio* parent; ++ } sections; ++ ++ //------------------------------------------------------------------------------ ++ public: ++ friend class Segments; ++ class Segments ++ { ++ public: ++ //------------------------------------------------------------------------------ ++ Segments( elfio* parent_ ) : parent( parent_ ) {} ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half size() const { return (Elf_Half)parent->segments_.size(); } ++ ++ //------------------------------------------------------------------------------ ++ segment* operator[]( unsigned int index ) const ++ { ++ return parent->segments_[index]; ++ } ++ ++ //------------------------------------------------------------------------------ ++ segment* add() { return parent->create_segment(); } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::iterator begin() ++ { ++ return parent->segments_.begin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::iterator end() ++ { ++ return parent->segments_.end(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::const_iterator begin() const ++ { ++ return parent->segments_.cbegin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::const_iterator end() const ++ { ++ return parent->segments_.cend(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elfio* parent; ++ } segments; ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elf_header* header; ++ std::vector<section*> sections_; ++ std::vector<segment*> segments_; ++ endianess_convertor convertor; ++ ++ Elf_Xword current_file_pos; ++}; ++ ++} // namespace ELFIO ++ ++ ++/*** Start of inlined file: elfio_symbols.hpp ***/ ++#ifndef ELFIO_SYMBOLS_HPP ++#define ELFIO_SYMBOLS_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class symbol_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ symbol_section_accessor_template( const elfio& elf_file_, ++ S* symbol_section_ ) ++ : elf_file( elf_file_ ), symbol_section( symbol_section_ ) ++ { ++ find_hash_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_symbols_num() const ++ { ++ Elf_Xword nRet = 0; ++ if ( 0 != symbol_section->get_entry_size() ) { ++ nRet = ++ symbol_section->get_size() / symbol_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( Elf_Xword index, ++ std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ ret = generic_get_symbol<Elf32_Sym>( index, name, value, size, bind, ++ type, section_index, other ); ++ } ++ else { ++ ret = generic_get_symbol<Elf64_Sym>( index, name, value, size, bind, ++ type, section_index, other ); ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( const std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( 0 != get_hash_table_index() ) { ++ Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); ++ Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + ++ sizeof( Elf_Word ) ); ++ Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); ++ Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + ++ ( 2 + val % nbucket ) * ++ sizeof( Elf_Word ) ); ++ std::string str; ++ get_symbol( y, str, value, size, bind, type, section_index, other ); ++ while ( str != name && STN_UNDEF != y && y < nchain ) { ++ y = *(const Elf_Word*)( hash_section->get_data() + ++ ( 2 + nbucket + y ) * ++ sizeof( Elf_Word ) ); ++ get_symbol( y, str, value, size, bind, type, section_index, ++ other ); ++ } ++ if ( str == name ) { ++ ret = true; ++ } ++ } ++ else { ++ for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) { ++ std::string symbol_name; ++ if ( get_symbol( i, symbol_name, value, size, bind, type, ++ section_index, other ) ) { ++ if ( symbol_name == name ) { ++ ret = true; ++ } ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( const Elf64_Addr& value, ++ std::string& name, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ Elf_Xword idx = 0; ++ bool match = false; ++ Elf64_Addr v = 0; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ match = generic_search_symbols<Elf32_Sym>( ++ [&]( const Elf32_Sym* sym ) { ++ return convertor( sym->st_value ) == value; ++ }, ++ idx ); ++ } ++ else { ++ match = generic_search_symbols<Elf64_Sym>( ++ [&]( const Elf64_Sym* sym ) { ++ return convertor( sym->st_value ) == value; ++ }, ++ idx ); ++ } ++ ++ if ( match ) { ++ return get_symbol( idx, name, v, size, bind, type, section_index, ++ other ); ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ Elf_Word nRet; ++ ++ if ( symbol_section->get_size() == 0 ) { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_add_symbol<Elf32_Sym>( 0, 0, 0, 0, 0, 0 ); ++ } ++ else { ++ nRet = generic_add_symbol<Elf64_Sym>( 0, 0, 0, 0, 0, 0 ); ++ } ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info, ++ other, shndx ); ++ } ++ else { ++ nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info, ++ other, shndx ); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, ++ shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( string_section_accessor& pStrWriter, ++ const char* str, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ Elf_Word index = pStrWriter.add_string( str ); ++ return add_symbol( index, value, size, info, other, shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( string_section_accessor& pStrWriter, ++ const char* str, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ return add_symbol( pStrWriter, str, value, size, ++ ELF_ST_INFO( bind, type ), other, shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword arrange_local_symbols( ++ std::function<void( Elf_Xword first, Elf_Xword second )> func = ++ nullptr ) ++ { ++ int nRet = 0; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_arrange_local_symbols<Elf32_Sym>( func ); ++ } ++ else { ++ nRet = generic_arrange_local_symbols<Elf64_Sym>( func ); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void find_hash_section() ++ { ++ hash_section = 0; ++ hash_section_index = 0; ++ Elf_Half nSecNo = elf_file.sections.size(); ++ for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { ++ const section* sec = elf_file.sections[i]; ++ if ( sec->get_link() == symbol_section->get_index() ) { ++ hash_section = sec; ++ hash_section_index = i; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_string_table_index() const ++ { ++ return (Elf_Half)symbol_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_hash_table_index() const { return hash_section_index; } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> const T* generic_get_symbol_ptr( Elf_Xword index ) const ++ { ++ if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { ++ const T* pSym = reinterpret_cast<const T*>( ++ symbol_section->get_data() + ++ index * symbol_section->get_entry_size() ); ++ ++ return pSym; ++ } ++ ++ return nullptr; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ bool generic_search_symbols( std::function<bool( const T* )> match, ++ Elf_Xword& idx ) const ++ { ++ for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) { ++ const T* symPtr = generic_get_symbol_ptr<T>( i ); ++ ++ if ( symPtr == nullptr ) ++ return false; ++ ++ if ( match( symPtr ) ) { ++ idx = i; ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ bool generic_get_symbol( Elf_Xword index, ++ std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { ++ const T* pSym = reinterpret_cast<const T*>( ++ symbol_section->get_data() + ++ index * symbol_section->get_entry_size() ); ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ section* string_section = ++ elf_file.sections[get_string_table_index()]; ++ string_section_accessor str_reader( string_section ); ++ const char* pStr = ++ str_reader.get_string( convertor( pSym->st_name ) ); ++ if ( 0 != pStr ) { ++ name = pStr; ++ } ++ value = convertor( pSym->st_value ); ++ size = convertor( pSym->st_size ); ++ bind = ELF_ST_BIND( pSym->st_info ); ++ type = ELF_ST_TYPE( pSym->st_info ); ++ section_index = convertor( pSym->st_shndx ); ++ other = pSym->st_other; ++ ++ ret = true; ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ Elf_Word generic_add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.st_name = convertor( name ); ++ entry.st_value = value; ++ entry.st_value = convertor( entry.st_value ); ++ entry.st_size = size; ++ entry.st_size = convertor( entry.st_size ); ++ entry.st_info = convertor( info ); ++ entry.st_other = convertor( other ); ++ entry.st_shndx = convertor( shndx ); ++ ++ symbol_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ ++ Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1; ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ Elf_Xword generic_arrange_local_symbols( ++ std::function<void( Elf_Xword first, Elf_Xword second )> func ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ const Elf_Xword size = symbol_section->get_entry_size(); ++ ++ Elf_Xword first_not_local = ++ 1; // Skip the first entry. It is always NOTYPE ++ Elf_Xword current = 0; ++ Elf_Xword count = get_symbols_num(); ++ ++ while ( true ) { ++ T* p1 = nullptr; ++ T* p2 = nullptr; ++ ++ while ( first_not_local < count ) { ++ p1 = const_cast<T*>( ++ generic_get_symbol_ptr<T>( first_not_local ) ); ++ if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL ) ++ break; ++ ++first_not_local; ++ } ++ ++ current = first_not_local + 1; ++ while ( current < count ) { ++ p2 = const_cast<T*>( generic_get_symbol_ptr<T>( current ) ); ++ if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL ) ++ break; ++ ++current; ++ } ++ ++ if ( first_not_local < count && current < count ) { ++ if ( func ) ++ func( first_not_local, current ); ++ ++ // Swap the symbols ++ T tmp; ++ std::copy( p1, p1 + 1, &tmp ); ++ std::copy( p2, p2 + 1, p1 ); ++ std::copy( &tmp, &tmp + 1, p2 ); ++ } ++ else { ++ // Update 'info' field of the section ++ symbol_section->set_info( first_not_local ); ++ break; ++ } ++ } ++ ++ // Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1; ++ ++ return first_not_local; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* symbol_section; ++ Elf_Half hash_section_index; ++ const section* hash_section; ++}; ++ ++using symbol_section_accessor = symbol_section_accessor_template<section>; ++using const_symbol_section_accessor = ++ symbol_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SYMBOLS_HPP ++ ++/*** End of inlined file: elfio_symbols.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_note.hpp ***/ ++#ifndef ELFIO_NOTE_HPP ++#define ELFIO_NOTE_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++// There are discrepancies in documentations. SCO documentation ++// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section) ++// requires 8 byte entries alignment for 64-bit ELF file, ++// but Oracle's definition uses the same structure ++// for 32-bit and 64-bit formats. ++// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html) ++// ++// It looks like EM_X86_64 Linux implementation is similar to Oracle's ++// definition. Therefore, the same alignment works for both formats ++//------------------------------------------------------------------------------ ++ ++//------------------------------------------------------------------------------ ++template <class S> class note_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ note_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), note_section( section_ ) ++ { ++ process_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word get_notes_num() const ++ { ++ return (Elf_Word)note_start_positions.size(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_note( Elf_Word index, ++ Elf_Word& type, ++ std::string& name, ++ void*& desc, ++ Elf_Word& descSize ) const ++ { ++ if ( index >= note_section->get_size() ) { ++ return false; ++ } ++ ++ const char* pData = ++ note_section->get_data() + note_start_positions[index]; ++ int align = sizeof( Elf_Word ); ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ type = convertor( *(const Elf_Word*)( pData + 2 * align ) ); ++ Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); ++ descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); ++ ++ Elf_Xword max_name_size = ++ note_section->get_size() - note_start_positions[index]; ++ if ( namesz < 1 || namesz > max_name_size || ++ (Elf_Xword)namesz + descSize > max_name_size ) { ++ return false; ++ } ++ name.assign( pData + 3 * align, namesz - 1 ); ++ if ( 0 == descSize ) { ++ desc = 0; ++ } ++ else { ++ desc = ++ const_cast<char*>( pData + 3 * align + ++ ( ( namesz + align - 1 ) / align ) * align ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_note( Elf_Word type, ++ const std::string& name, ++ const void* desc, ++ Elf_Word descSize ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ int align = sizeof( Elf_Word ); ++ Elf_Word nameLen = (Elf_Word)name.size() + 1; ++ Elf_Word nameLenConv = convertor( nameLen ); ++ std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align ); ++ Elf_Word descSizeConv = convertor( descSize ); ++ ++ buffer.append( reinterpret_cast<char*>( &descSizeConv ), align ); ++ type = convertor( type ); ++ buffer.append( reinterpret_cast<char*>( &type ), align ); ++ buffer.append( name ); ++ buffer.append( 1, '\x00' ); ++ const char pad[] = { '\0', '\0', '\0', '\0' }; ++ if ( nameLen % align != 0 ) { ++ buffer.append( pad, align - nameLen % align ); ++ } ++ if ( desc != 0 && descSize != 0 ) { ++ buffer.append( reinterpret_cast<const char*>( desc ), descSize ); ++ if ( descSize % align != 0 ) { ++ buffer.append( pad, align - descSize % align ); ++ } ++ } ++ ++ note_start_positions.push_back( note_section->get_size() ); ++ note_section->append_data( buffer ); ++ } ++ ++ private: ++ //------------------------------------------------------------------------------ ++ void process_section() ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ const char* data = note_section->get_data(); ++ Elf_Xword size = note_section->get_size(); ++ Elf_Xword current = 0; ++ ++ note_start_positions.clear(); ++ ++ // Is it empty? ++ if ( 0 == data || 0 == size ) { ++ return; ++ } ++ ++ Elf_Word align = sizeof( Elf_Word ); ++ while ( current + (Elf_Xword)3 * align <= size ) { ++ note_start_positions.push_back( current ); ++ Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) ); ++ Elf_Word descsz = convertor( ++ *(const Elf_Word*)( data + current + sizeof( namesz ) ) ); ++ ++ current += (Elf_Xword)3 * sizeof( Elf_Word ) + ++ ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align + ++ ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* note_section; ++ std::vector<Elf_Xword> note_start_positions; ++}; ++ ++using note_section_accessor = note_section_accessor_template<section>; ++using const_note_section_accessor = ++ note_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_NOTE_HPP ++ ++/*** End of inlined file: elfio_note.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_relocation.hpp ***/ ++#ifndef ELFIO_RELOCATION_HPP ++#define ELFIO_RELOCATION_HPP ++ ++namespace ELFIO { ++ ++template <typename T> struct get_sym_and_type; ++template <> struct get_sym_and_type<Elf32_Rel> ++{ ++ static int get_r_sym( Elf_Xword info ) ++ { ++ return ELF32_R_SYM( (Elf_Word)info ); ++ } ++ static int get_r_type( Elf_Xword info ) ++ { ++ return ELF32_R_TYPE( (Elf_Word)info ); ++ } ++}; ++template <> struct get_sym_and_type<Elf32_Rela> ++{ ++ static int get_r_sym( Elf_Xword info ) ++ { ++ return ELF32_R_SYM( (Elf_Word)info ); ++ } ++ static int get_r_type( Elf_Xword info ) ++ { ++ return ELF32_R_TYPE( (Elf_Word)info ); ++ } ++}; ++template <> struct get_sym_and_type<Elf64_Rel> ++{ ++ static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } ++ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } ++}; ++template <> struct get_sym_and_type<Elf64_Rela> ++{ ++ static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } ++ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } ++}; ++ ++//------------------------------------------------------------------------------ ++template <class S> class relocation_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), relocation_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_entries_num() const ++ { ++ Elf_Xword nRet = 0; ++ ++ if ( 0 != relocation_section->get_entry_size() ) { ++ nRet = relocation_section->get_size() / ++ relocation_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_get_entry_rel<Elf32_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_get_entry_rela<Elf32_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ else { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_get_entry_rel<Elf64_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_get_entry_rela<Elf64_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf64_Addr& symbolValue, ++ std::string& symbolName, ++ Elf_Word& type, ++ Elf_Sxword& addend, ++ Elf_Sxword& calcValue ) const ++ { ++ // Do regular job ++ Elf_Word symbol; ++ bool ret = get_entry( index, offset, symbol, type, addend ); ++ ++ // Find the symbol ++ Elf_Xword size; ++ unsigned char bind; ++ unsigned char symbolType; ++ Elf_Half section; ++ unsigned char other; ++ ++ symbol_section_accessor symbols( ++ elf_file, elf_file.sections[get_symbol_table_index()] ); ++ ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size, ++ bind, symbolType, section, other ); ++ ++ if ( ret ) { // Was it successful? ++ switch ( type ) { ++ case R_386_NONE: // none ++ calcValue = 0; ++ break; ++ case R_386_32: // S + A ++ calcValue = symbolValue + addend; ++ break; ++ case R_386_PC32: // S + A - P ++ calcValue = symbolValue + addend - offset; ++ break; ++ case R_386_GOT32: // G + A - P ++ calcValue = 0; ++ break; ++ case R_386_PLT32: // L + A - P ++ calcValue = 0; ++ break; ++ case R_386_COPY: // none ++ calcValue = 0; ++ break; ++ case R_386_GLOB_DAT: // S ++ case R_386_JMP_SLOT: // S ++ calcValue = symbolValue; ++ break; ++ case R_386_RELATIVE: // B + A ++ calcValue = addend; ++ break; ++ case R_386_GOTOFF: // S + A - GOT ++ calcValue = 0; ++ break; ++ case R_386_GOTPC: // GOT + A - P ++ calcValue = 0; ++ break; ++ default: // Not recognized symbol! ++ calcValue = 0; ++ break; ++ } ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool set_entry( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword addend ) ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_set_entry_rel<Elf32_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_set_entry_rela<Elf32_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ else { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_set_entry_rel<Elf64_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_set_entry_rela<Elf64_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Xword info ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Rel>( offset, info ); ++ } ++ else { ++ generic_add_entry<Elf64_Rel>( offset, info ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type ) ++ { ++ Elf_Xword info; ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ ++ add_entry( offset, info ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Rela>( offset, info, addend ); ++ } ++ else { ++ generic_add_entry<Elf64_Rela>( offset, info, addend ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, ++ Elf_Word symbol, ++ unsigned char type, ++ Elf_Sxword addend ) ++ { ++ Elf_Xword info; ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ ++ add_entry( offset, info, addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( string_section_accessor str_writer, ++ const char* str, ++ symbol_section_accessor sym_writer, ++ Elf64_Addr value, ++ Elf_Word size, ++ unsigned char sym_info, ++ unsigned char other, ++ Elf_Half shndx, ++ Elf64_Addr offset, ++ unsigned char type ) ++ { ++ Elf_Word str_index = str_writer.add_string( str ); ++ Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, ++ sym_info, other, shndx ); ++ add_entry( offset, sym_index, type ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void swap_symbols( Elf_Xword first, Elf_Xword second ) ++ { ++ Elf64_Addr offset; ++ Elf_Word symbol; ++ Elf_Word rtype; ++ Elf_Sxword addend; ++ for ( Elf_Word i = 0; i < get_entries_num(); i++ ) { ++ get_entry( i, offset, symbol, rtype, addend ); ++ if ( symbol == first ) { ++ set_entry( i, offset, (Elf_Word)second, rtype, addend ); ++ } ++ if ( symbol == second ) { ++ set_entry( i, offset, (Elf_Word)first, rtype, addend ); ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ Elf_Half get_symbol_table_index() const ++ { ++ return (Elf_Half)relocation_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_rel( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ); ++ offset = convertor( pEntry->r_offset ); ++ Elf_Xword tmp = convertor( pEntry->r_info ); ++ symbol = get_sym_and_type<T>::get_r_sym( tmp ); ++ type = get_sym_and_type<T>::get_r_type( tmp ); ++ addend = 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_rela( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ); ++ offset = convertor( pEntry->r_offset ); ++ Elf_Xword tmp = convertor( pEntry->r_info ); ++ symbol = get_sym_and_type<T>::get_r_sym( tmp ); ++ type = get_sym_and_type<T>::get_r_type( tmp ); ++ addend = convertor( pEntry->r_addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_set_entry_rel( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T* pEntry = const_cast<T*>( reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ) ); ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ pEntry->r_offset = offset; ++ pEntry->r_offset = convertor( pEntry->r_offset ); ++ pEntry->r_info = convertor( pEntry->r_info ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_set_entry_rela( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword addend ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T* pEntry = const_cast<T*>( reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ) ); ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ pEntry->r_offset = offset; ++ pEntry->r_addend = addend; ++ pEntry->r_offset = convertor( pEntry->r_offset ); ++ pEntry->r_info = convertor( pEntry->r_info ); ++ pEntry->r_addend = convertor( pEntry->r_addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_add_entry( Elf64_Addr offset, Elf_Xword info ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.r_offset = offset; ++ entry.r_info = info; ++ entry.r_offset = convertor( entry.r_offset ); ++ entry.r_info = convertor( entry.r_info ); ++ ++ relocation_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void ++ generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.r_offset = offset; ++ entry.r_info = info; ++ entry.r_addend = addend; ++ entry.r_offset = convertor( entry.r_offset ); ++ entry.r_info = convertor( entry.r_info ); ++ entry.r_addend = convertor( entry.r_addend ); ++ ++ relocation_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* relocation_section; ++}; ++ ++using relocation_section_accessor = ++ relocation_section_accessor_template<section>; ++using const_relocation_section_accessor = ++ relocation_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_RELOCATION_HPP ++ ++/*** End of inlined file: elfio_relocation.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_dynamic.hpp ***/ ++#ifndef ELFIO_DYNAMIC_HPP ++#define ELFIO_DYNAMIC_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class dynamic_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), dynamic_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_entries_num() const ++ { ++ Elf_Xword nRet = 0; ++ ++ if ( 0 != dynamic_section->get_entry_size() ) { ++ nRet = ++ dynamic_section->get_size() / dynamic_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf_Xword& tag, ++ Elf_Xword& value, ++ std::string& str ) const ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_get_entry_dyn<Elf32_Dyn>( index, tag, value ); ++ } ++ else { ++ generic_get_entry_dyn<Elf64_Dyn>( index, tag, value ); ++ } ++ ++ // If the tag may have a string table reference, prepare the string ++ if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || ++ tag == DT_RUNPATH ) { ++ string_section_accessor strsec = ++ elf_file.sections[get_string_table_index()]; ++ const char* result = strsec.get_string( value ); ++ if ( 0 == result ) { ++ str.clear(); ++ return false; ++ } ++ str = result; ++ } ++ else { ++ str.clear(); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf_Xword tag, Elf_Xword value ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Dyn>( tag, value ); ++ } ++ else { ++ generic_add_entry<Elf64_Dyn>( tag, value ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf_Xword tag, const std::string& str ) ++ { ++ string_section_accessor strsec = ++ elf_file.sections[get_string_table_index()]; ++ Elf_Xword value = strsec.add_string( str ); ++ add_entry( tag, value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ Elf_Half get_string_table_index() const ++ { ++ return (Elf_Half)dynamic_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_dyn( Elf_Xword index, ++ Elf_Xword& tag, ++ Elf_Xword& value ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ // Check unusual case when dynamic section has no data ++ if ( dynamic_section->get_data() == 0 || ++ ( index + 1 ) * dynamic_section->get_entry_size() > ++ dynamic_section->get_size() ) { ++ tag = DT_NULL; ++ value = 0; ++ return; ++ } ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ dynamic_section->get_data() + ++ index * dynamic_section->get_entry_size() ); ++ tag = convertor( pEntry->d_tag ); ++ switch ( tag ) { ++ case DT_NULL: ++ case DT_SYMBOLIC: ++ case DT_TEXTREL: ++ case DT_BIND_NOW: ++ value = 0; ++ break; ++ case DT_NEEDED: ++ case DT_PLTRELSZ: ++ case DT_RELASZ: ++ case DT_RELAENT: ++ case DT_STRSZ: ++ case DT_SYMENT: ++ case DT_SONAME: ++ case DT_RPATH: ++ case DT_RELSZ: ++ case DT_RELENT: ++ case DT_PLTREL: ++ case DT_INIT_ARRAYSZ: ++ case DT_FINI_ARRAYSZ: ++ case DT_RUNPATH: ++ case DT_FLAGS: ++ case DT_PREINIT_ARRAYSZ: ++ value = convertor( pEntry->d_un.d_val ); ++ break; ++ case DT_PLTGOT: ++ case DT_HASH: ++ case DT_STRTAB: ++ case DT_SYMTAB: ++ case DT_RELA: ++ case DT_INIT: ++ case DT_FINI: ++ case DT_REL: ++ case DT_DEBUG: ++ case DT_JMPREL: ++ case DT_INIT_ARRAY: ++ case DT_FINI_ARRAY: ++ case DT_PREINIT_ARRAY: ++ default: ++ value = convertor( pEntry->d_un.d_ptr ); ++ break; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> void generic_add_entry( Elf_Xword tag, Elf_Xword value ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ ++ switch ( tag ) { ++ case DT_NULL: ++ case DT_SYMBOLIC: ++ case DT_TEXTREL: ++ case DT_BIND_NOW: ++ value = 0; ++ case DT_NEEDED: ++ case DT_PLTRELSZ: ++ case DT_RELASZ: ++ case DT_RELAENT: ++ case DT_STRSZ: ++ case DT_SYMENT: ++ case DT_SONAME: ++ case DT_RPATH: ++ case DT_RELSZ: ++ case DT_RELENT: ++ case DT_PLTREL: ++ case DT_INIT_ARRAYSZ: ++ case DT_FINI_ARRAYSZ: ++ case DT_RUNPATH: ++ case DT_FLAGS: ++ case DT_PREINIT_ARRAYSZ: ++ entry.d_un.d_val = convertor( value ); ++ break; ++ case DT_PLTGOT: ++ case DT_HASH: ++ case DT_STRTAB: ++ case DT_SYMTAB: ++ case DT_RELA: ++ case DT_INIT: ++ case DT_FINI: ++ case DT_REL: ++ case DT_DEBUG: ++ case DT_JMPREL: ++ case DT_INIT_ARRAY: ++ case DT_FINI_ARRAY: ++ case DT_PREINIT_ARRAY: ++ default: ++ entry.d_un.d_ptr = convertor( value ); ++ break; ++ } ++ ++ entry.d_tag = convertor( tag ); ++ ++ dynamic_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* dynamic_section; ++}; ++ ++using dynamic_section_accessor = dynamic_section_accessor_template<section>; ++using const_dynamic_section_accessor = ++ dynamic_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_DYNAMIC_HPP ++ ++/*** End of inlined file: elfio_dynamic.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_modinfo.hpp ***/ ++#ifndef ELFIO_MODINFO_HPP ++#define ELFIO_MODINFO_HPP ++ ++#include <string> ++#include <vector> ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class modinfo_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ modinfo_section_accessor_template( S* section_ ) ++ : modinfo_section( section_ ) ++ { ++ process_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); } ++ ++ //------------------------------------------------------------------------------ ++ bool ++ get_attribute( Elf_Word no, std::string& field, std::string& value ) const ++ { ++ if ( no < content.size() ) { ++ field = content[no].first; ++ value = content[no].second; ++ return true; ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_attribute( std::string field_name, std::string& value ) const ++ { ++ for ( auto i = content.begin(); i != content.end(); i++ ) { ++ if ( field_name == i->first ) { ++ value = i->second; ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_attribute( std::string field, std::string value ) ++ { ++ Elf_Word current_position = 0; ++ ++ if ( modinfo_section ) { ++ // Strings are addeded to the end of the current section data ++ current_position = (Elf_Word)modinfo_section->get_size(); ++ ++ std::string attribute = field + "=" + value; ++ ++ modinfo_section->append_data( attribute + '\0' ); ++ content.push_back( ++ std::pair<std::string, std::string>( field, value ) ); ++ } ++ ++ return current_position; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ void process_section() ++ { ++ const char* pdata = modinfo_section->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i = 0; ++ while ( i < modinfo_section->get_size() ) { ++ while ( i < modinfo_section->get_size() && !pdata[i] ) ++ i++; ++ if ( i < modinfo_section->get_size() ) { ++ std::string info = pdata + i; ++ size_t loc = info.find( '=' ); ++ std::pair<std::string, std::string> attribute( ++ info.substr( 0, loc ), info.substr( loc + 1 ) ); ++ ++ content.push_back( attribute ); ++ ++ i += info.length(); ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ S* modinfo_section; ++ std::vector<std::pair<std::string, std::string>> content; ++}; ++ ++using modinfo_section_accessor = modinfo_section_accessor_template<section>; ++using const_modinfo_section_accessor = ++ modinfo_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_MODINFO_HPP ++ ++/*** End of inlined file: elfio_modinfo.hpp ***/ ++ ++#ifdef _MSC_VER ++#pragma warning( pop ) ++#endif ++ ++#endif // ELFIO_HPP ++ ++/*** End of inlined file: elfio.hpp ***/ ++ ++ ++namespace ELFIO { ++ ++static struct class_table_t ++{ ++ const char key; ++ const char* str; ++} class_table[] = { ++ { ELFCLASS32, "ELF32" }, ++ { ELFCLASS64, "ELF64" }, ++}; ++ ++static struct endian_table_t ++{ ++ const char key; ++ const char* str; ++} endian_table[] = { ++ { ELFDATANONE, "None" }, ++ { ELFDATA2LSB, "Little endian" }, ++ { ELFDATA2MSB, "Big endian" }, ++}; ++ ++static struct version_table_t ++{ ++ const Elf64_Word key; ++ const char* str; ++} version_table[] = { ++ { EV_NONE, "None" }, ++ { EV_CURRENT, "Current" }, ++}; ++ ++static struct type_table_t ++{ ++ const Elf32_Half key; ++ const char* str; ++} type_table[] = { ++ { ET_NONE, "No file type" }, { ET_REL, "Relocatable file" }, ++ { ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" }, ++ { ET_CORE, "Core file" }, ++}; ++ ++static struct machine_table_t ++{ ++ const Elf64_Half key; ++ const char* str; ++} machine_table[] = { ++ { EM_NONE, "No machine" }, ++ { EM_M32, "AT&T WE 32100" }, ++ { EM_SPARC, "SUN SPARC" }, ++ { EM_386, "Intel 80386" }, ++ { EM_68K, "Motorola m68k family" }, ++ { EM_88K, "Motorola m88k family" }, ++ { EM_486, "Intel 80486// Reserved for future use" }, ++ { EM_860, "Intel 80860" }, ++ { EM_MIPS, "MIPS R3000 (officially, big-endian only)" }, ++ { EM_S370, "IBM System/370" }, ++ { EM_MIPS_RS3_LE, ++ "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, ++ { EM_res011, "Reserved" }, ++ { EM_res012, "Reserved" }, ++ { EM_res013, "Reserved" }, ++ { EM_res014, "Reserved" }, ++ { EM_PARISC, "HPPA" }, ++ { EM_res016, "Reserved" }, ++ { EM_VPP550, "Fujitsu VPP500" }, ++ { EM_SPARC32PLUS, "Sun's v8plus" }, ++ { EM_960, "Intel 80960" }, ++ { EM_PPC, "PowerPC" }, ++ { EM_PPC64, "64-bit PowerPC" }, ++ { EM_S390, "IBM S/390" }, ++ { EM_SPU, "Sony/Toshiba/IBM SPU" }, ++ { EM_res024, "Reserved" }, ++ { EM_res025, "Reserved" }, ++ { EM_res026, "Reserved" }, ++ { EM_res027, "Reserved" }, ++ { EM_res028, "Reserved" }, ++ { EM_res029, "Reserved" }, ++ { EM_res030, "Reserved" }, ++ { EM_res031, "Reserved" }, ++ { EM_res032, "Reserved" }, ++ { EM_res033, "Reserved" }, ++ { EM_res034, "Reserved" }, ++ { EM_res035, "Reserved" }, ++ { EM_V800, "NEC V800 series" }, ++ { EM_FR20, "Fujitsu FR20" }, ++ { EM_RH32, "TRW RH32" }, ++ { EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" }, ++ { EM_RCE, "Old name for MCore" }, ++ { EM_ARM, "ARM" }, ++ { EM_OLD_ALPHA, "Digital Alpha" }, ++ { EM_SH, "Renesas (formerly Hitachi) / SuperH SH" }, ++ { EM_SPARCV9, "SPARC v9 64-bit" }, ++ { EM_TRICORE, "Siemens Tricore embedded processor" }, ++ { EM_ARC, "ARC Cores" }, ++ { EM_H8_300, "Renesas (formerly Hitachi) H8/300" }, ++ { EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" }, ++ { EM_H8S, "Renesas (formerly Hitachi) H8S" }, ++ { EM_H8_500, "Renesas (formerly Hitachi) H8/500" }, ++ { EM_IA_64, "Intel IA-64 Processor" }, ++ { EM_MIPS_X, "Stanford MIPS-X" }, ++ { EM_COLDFIRE, "Motorola Coldfire" }, ++ { EM_68HC12, "Motorola M68HC12" }, ++ { EM_MMA, "Fujitsu Multimedia Accelerator" }, ++ { EM_PCP, "Siemens PCP" }, ++ { EM_NCPU, "Sony nCPU embedded RISC processor" }, ++ { EM_NDR1, "Denso NDR1 microprocesspr" }, ++ { EM_STARCORE, "Motorola Star*Core processor" }, ++ { EM_ME16, "Toyota ME16 processor" }, ++ { EM_ST100, "STMicroelectronics ST100 processor" }, ++ { EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" }, ++ { EM_X86_64, "Advanced Micro Devices X86-64 processor" }, ++ { EM_PDSP, "Sony DSP Processor" }, ++ { EM_PDP10, "Digital Equipment Corp. PDP-10" }, ++ { EM_PDP11, "Digital Equipment Corp. PDP-11" }, ++ { EM_FX66, "Siemens FX66 microcontroller" }, ++ { EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" }, ++ { EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" }, ++ { EM_68HC16, "Motorola MC68HC16 Microcontroller" }, ++ { EM_68HC11, "Motorola MC68HC11 Microcontroller" }, ++ { EM_68HC08, "Motorola MC68HC08 Microcontroller" }, ++ { EM_68HC05, "Motorola MC68HC05 Microcontroller" }, ++ { EM_SVX, "Silicon Graphics SVx" }, ++ { EM_ST19, "STMicroelectronics ST19 8-bit cpu" }, ++ { EM_VAX, "Digital VAX" }, ++ { EM_CRIS, "Axis Communications 32-bit embedded processor" }, ++ { EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" }, ++ { EM_FIREPATH, "Element 14 64-bit DSP processor" }, ++ { EM_ZSP, "LSI Logic's 16-bit DSP processor" }, ++ { EM_MMIX, "Donald Knuth's educational 64-bit processor" }, ++ { EM_HUANY, "Harvard's machine-independent format" }, ++ { EM_PRISM, "SiTera Prism" }, ++ { EM_AVR, "Atmel AVR 8-bit microcontroller" }, ++ { EM_FR30, "Fujitsu FR30" }, ++ { EM_D10V, "Mitsubishi D10V" }, ++ { EM_D30V, "Mitsubishi D30V" }, ++ { EM_V850, "NEC v850" }, ++ { EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" }, ++ { EM_MN10300, "Matsushita MN10300" }, ++ { EM_MN10200, "Matsushita MN10200" }, ++ { EM_PJ, "picoJava" }, ++ { EM_OPENRISC, "OpenRISC 32-bit embedded processor" }, ++ { EM_ARC_A5, "ARC Cores Tangent-A5" }, ++ { EM_XTENSA, "Tensilica Xtensa Architecture" }, ++ { EM_VIDEOCORE, "Alphamosaic VideoCore processor" }, ++ { EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" }, ++ { EM_NS32K, "National Semiconductor 32000 series" }, ++ { EM_TPC, "Tenor Network TPC processor" }, ++ { EM_SNP1K, "Trebia SNP 1000 processor" }, ++ { EM_ST200, "STMicroelectronics ST200 microcontroller" }, ++ { EM_IP2K, "Ubicom IP2022 micro controller" }, ++ { EM_MAX, "MAX Processor" }, ++ { EM_CR, "National Semiconductor CompactRISC" }, ++ { EM_F2MC16, "Fujitsu F2MC16" }, ++ { EM_MSP430, "TI msp430 micro controller" }, ++ { EM_BLACKFIN, "ADI Blackfin" }, ++ { EM_SE_C33, "S1C33 Family of Seiko Epson processors" }, ++ { EM_SEP, "Sharp embedded microprocessor" }, ++ { EM_ARCA, "Arca RISC Microprocessor" }, ++ { EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of " ++ "Peking University" }, ++ { EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" }, ++ { EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" }, ++ { EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" }, ++ { EM_CRX, "National Semiconductor CRX" }, ++ { EM_XGATE, "Motorola XGATE embedded processor" }, ++ { EM_C166, "Infineon C16x/XC16x processor" }, ++ { EM_M16C, "Renesas M16C series microprocessors" }, ++ { EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" }, ++ { EM_CE, "Freescale Communication Engine RISC core" }, ++ { EM_M32C, "Renesas M32C series microprocessors" }, ++ { EM_res121, "Reserved" }, ++ { EM_res122, "Reserved" }, ++ { EM_res123, "Reserved" }, ++ { EM_res124, "Reserved" }, ++ { EM_res125, "Reserved" }, ++ { EM_res126, "Reserved" }, ++ { EM_res127, "Reserved" }, ++ { EM_res128, "Reserved" }, ++ { EM_res129, "Reserved" }, ++ { EM_res130, "Reserved" }, ++ { EM_TSK3000, "Altium TSK3000 core" }, ++ { EM_RS08, "Freescale RS08 embedded processor" }, ++ { EM_res133, "Reserved" }, ++ { EM_ECOG2, "Cyan Technology eCOG2 microprocessor" }, ++ { EM_SCORE, "Sunplus Score" }, ++ { EM_SCORE7, "Sunplus S+core7 RISC processor" }, ++ { EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" }, ++ { EM_VIDEOCORE3, "Broadcom VideoCore III processor" }, ++ { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, ++ { EM_SE_C17, "Seiko Epson C17 family" }, ++ { EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" }, ++ { EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" }, ++ { EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" }, ++ { EM_res143, "Reserved" }, ++ { EM_res144, "Reserved" }, ++ { EM_res145, "Reserved" }, ++ { EM_res146, "Reserved" }, ++ { EM_res147, "Reserved" }, ++ { EM_res148, "Reserved" }, ++ { EM_res149, "Reserved" }, ++ { EM_res150, "Reserved" }, ++ { EM_res151, "Reserved" }, ++ { EM_res152, "Reserved" }, ++ { EM_res153, "Reserved" }, ++ { EM_res154, "Reserved" }, ++ { EM_res155, "Reserved" }, ++ { EM_res156, "Reserved" }, ++ { EM_res157, "Reserved" }, ++ { EM_res158, "Reserved" }, ++ { EM_res159, "Reserved" }, ++ { EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" }, ++ { EM_CYPRESS_M8C, "Cypress M8C microprocessor" }, ++ { EM_R32C, "Renesas R32C series microprocessors" }, ++ { EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" }, ++ { EM_QDSP6, "QUALCOMM DSP6 Processor" }, ++ { EM_8051, "Intel 8051 and variants" }, ++ { EM_STXP7X, "STMicroelectronics STxP7x family" }, ++ { EM_NDS32, ++ "Andes Technology compact code size embedded RISC processor family" }, ++ { EM_ECOG1, "Cyan Technology eCOG1X family" }, ++ { EM_ECOG1X, "Cyan Technology eCOG1X family" }, ++ { EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, ++ { EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" }, ++ { EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" }, ++ { EM_CRAYNV2, "Cray Inc. NV2 vector architecture" }, ++ { EM_RX, "Renesas RX family" }, ++ { EM_METAG, "Imagination Technologies META processor architecture" }, ++ { EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" }, ++ { EM_ECOG16, "Cyan Technology eCOG16 family" }, ++ { EM_CR16, "National Semiconductor CompactRISC 16-bit processor" }, ++ { EM_ETPU, "Freescale Extended Time Processing Unit" }, ++ { EM_SLE9X, "Infineon Technologies SLE9X core" }, ++ { EM_L1OM, "Intel L1OM" }, ++ { EM_INTEL181, "Reserved by Intel" }, ++ { EM_INTEL182, "Reserved by Intel" }, ++ { EM_res183, "Reserved by ARM" }, ++ { EM_res184, "Reserved by ARM" }, ++ { EM_AVR32, "Atmel Corporation 32-bit microprocessor family" }, ++ { EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" }, ++ { EM_TILE64, "Tilera TILE64 multicore architecture family" }, ++ { EM_TILEPRO, "Tilera TILEPro multicore architecture family" }, ++ { EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" }, ++ { EM_CUDA, "NVIDIA CUDA architecture " }, ++}; ++ ++static struct section_type_table_t ++{ ++ const Elf64_Half key; ++ const char* str; ++} section_type_table[] = { ++ { SHT_NULL, "NULL" }, ++ { SHT_PROGBITS, "PROGBITS" }, ++ { SHT_SYMTAB, "SYMTAB" }, ++ { SHT_STRTAB, "STRTAB" }, ++ { SHT_RELA, "RELA" }, ++ { SHT_HASH, "HASH" }, ++ { SHT_DYNAMIC, "DYNAMIC" }, ++ { SHT_NOTE, "NOTE" }, ++ { SHT_NOBITS, "NOBITS" }, ++ { SHT_REL, "REL" }, ++ { SHT_SHLIB, "SHLIB" }, ++ { SHT_DYNSYM, "DYNSYM" }, ++ { SHT_INIT_ARRAY, "INIT_ARRAY" }, ++ { SHT_FINI_ARRAY, "FINI_ARRAY" }, ++ { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, ++ { SHT_GROUP, "GROUP" }, ++ { SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " }, ++}; ++ ++static struct segment_type_table_t ++{ ++ const Elf_Word key; ++ const char* str; ++} segment_type_table[] = { ++ { PT_NULL, "NULL" }, { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" }, ++ { PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" }, ++ { PT_PHDR, "PHDR" }, { PT_TLS, "TLS" }, ++}; ++ ++static struct segment_flag_table_t ++{ ++ const Elf_Word key; ++ const char* str; ++} segment_flag_table[] = { ++ { 0, "" }, { 1, "X" }, { 2, "W" }, { 3, "WX" }, ++ { 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" }, ++}; ++ ++static struct symbol_bind_t ++{ ++ const Elf_Word key; ++ const char* str; ++} symbol_bind_table[] = { ++ { STB_LOCAL, "LOCAL" }, { STB_GLOBAL, "GLOBAL" }, ++ { STB_WEAK, "WEAK" }, { STB_LOOS, "LOOS" }, ++ { STB_HIOS, "HIOS" }, { STB_MULTIDEF, "MULTIDEF" }, ++ { STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" }, ++}; ++ ++static struct symbol_type_t ++{ ++ const Elf_Word key; ++ const char* str; ++} symbol_type_table[] = { ++ { STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" }, ++ { STT_FUNC, "FUNC" }, { STT_SECTION, "SECTION" }, ++ { STT_FILE, "FILE" }, { STT_COMMON, "COMMON" }, ++ { STT_TLS, "TLS" }, { STT_LOOS, "LOOS" }, ++ { STT_HIOS, "HIOS" }, { STT_LOPROC, "LOPROC" }, ++ { STT_HIPROC, "HIPROC" }, ++}; ++ ++static struct dynamic_tag_t ++{ ++ const Elf_Word key; ++ const char* str; ++} dynamic_tag_table[] = { ++ { DT_NULL, "NULL" }, ++ { DT_NEEDED, "NEEDED" }, ++ { DT_PLTRELSZ, "PLTRELSZ" }, ++ { DT_PLTGOT, "PLTGOT" }, ++ { DT_HASH, "HASH" }, ++ { DT_STRTAB, "STRTAB" }, ++ { DT_SYMTAB, "SYMTAB" }, ++ { DT_RELA, "RELA" }, ++ { DT_RELASZ, "RELASZ" }, ++ { DT_RELAENT, "RELAENT" }, ++ { DT_STRSZ, "STRSZ" }, ++ { DT_SYMENT, "SYMENT" }, ++ { DT_INIT, "INIT" }, ++ { DT_FINI, "FINI" }, ++ { DT_SONAME, "SONAME" }, ++ { DT_RPATH, "RPATH" }, ++ { DT_SYMBOLIC, "SYMBOLIC" }, ++ { DT_REL, "REL" }, ++ { DT_RELSZ, "RELSZ" }, ++ { DT_RELENT, "RELENT" }, ++ { DT_PLTREL, "PLTREL" }, ++ { DT_DEBUG, "DEBUG" }, ++ { DT_TEXTREL, "TEXTREL" }, ++ { DT_JMPREL, "JMPREL" }, ++ { DT_BIND_NOW, "BIND_NOW" }, ++ { DT_INIT_ARRAY, "INIT_ARRAY" }, ++ { DT_FINI_ARRAY, "FINI_ARRAY" }, ++ { DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" }, ++ { DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" }, ++ { DT_RUNPATH, "RUNPATH" }, ++ { DT_FLAGS, "FLAGS" }, ++ { DT_ENCODING, "ENCODING" }, ++ { DT_PREINIT_ARRAY, "PREINIT_ARRAY" }, ++ { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, ++ { DT_MAXPOSTAGS, "MAXPOSTAGS" }, ++}; ++ ++static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; ++ ++//------------------------------------------------------------------------------ ++class dump ++{ ++#define DUMP_DEC_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right ++#define DUMP_HEX_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( '0' ) << std::hex << std::right ++#define DUMP_STR_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left ++ ++ public: ++ //------------------------------------------------------------------------------ ++ static void header( std::ostream& out, const elfio& reader ) ++ { ++ if ( !reader.get_header_size() ) { ++ return; ++ } ++ out << "ELF Header" << std::endl ++ << std::endl ++ << " Class: " << str_class( reader.get_class() ) << std::endl ++ << " Encoding: " << str_endian( reader.get_encoding() ) ++ << std::endl ++ << " ELFVersion: " << str_version( reader.get_elf_version() ) ++ << std::endl ++ << " Type: " << str_type( reader.get_type() ) << std::endl ++ << " Machine: " << str_machine( reader.get_machine() ) ++ << std::endl ++ << " Version: " << str_version( reader.get_version() ) ++ << std::endl ++ << " Entry: " ++ << "0x" << std::hex << reader.get_entry() << std::endl ++ << " Flags: " ++ << "0x" << std::hex << reader.get_flags() << std::endl ++ << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_headers( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Section Headers:" << std::endl; ++ if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Type Addr Size ES Flg Lk Inf " ++ "Al Name" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Type Addr Size " ++ " ES Flg" ++ << std::endl ++ << " Lk Inf Al Name" << std::endl; ++ } ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ section_header( out, i, sec, reader.get_class() ); ++ } ++ ++ out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" ++ << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_header( std::ostream& out, ++ Elf_Half no, ++ const section* sec, ++ unsigned char elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " ++ << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " ++ << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " ++ << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) ++ << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " ++ << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " ++ << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " ++ << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " ++ << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " ++ << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) ++ << " " << std::endl ++ << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " ++ << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_headers( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.segments.size(); ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Segment headers:" << std::endl; ++ if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size " ++ "Flags Align" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Type VirtAddr PhysAddr " ++ "Flags" ++ << std::endl ++ << " FileSize Mem.Size " ++ "Align" ++ << std::endl; ++ } ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { ++ segment* seg = reader.segments[i]; ++ segment_header( out, i, seg, reader.get_class() ); ++ } ++ ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_header( std::ostream& out, ++ Elf_Half no, ++ const segment* seg, ++ unsigned int elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " ++ << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " ++ << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() ++ << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() ++ << " " << DUMP_STR_FORMAT( 16 ) ++ << str_segment_flag( seg->get_flags() ) << " " << std::endl ++ << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_align() << " " << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void symbol_tables( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_SYMTAB == sec->get_type() || ++ SHT_DYNSYM == sec->get_type() ) { ++ symbol_section_accessor symbols( reader, sec ); ++ ++ Elf_Xword sym_no = symbols.get_symbols_num(); ++ if ( sym_no > 0 ) { ++ out << "Symbol table (" << sec->get_name() << ")" ++ << std::endl; ++ if ( reader.get_class() == ++ ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Value Size Type Bind " ++ "Sect Name" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Value Size Type " ++ " Bind Sect" ++ << std::endl ++ << " Name" << std::endl; ++ } ++ for ( Elf_Xword i = 0; i < sym_no; ++i ) { ++ std::string name; ++ Elf64_Addr value = 0; ++ Elf_Xword size = 0; ++ unsigned char bind = 0; ++ unsigned char type = 0; ++ Elf_Half section = 0; ++ unsigned char other = 0; ++ symbols.get_symbol( i, name, value, size, bind, type, ++ section, other ); ++ symbol_table( out, i, name, value, size, bind, type, ++ section, reader.get_class() ); ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void symbol_table( std::ostream& out, ++ Elf_Xword no, ++ std::string& name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ Elf_Half section, ++ unsigned int elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 ) ++ << size << " " << DUMP_STR_FORMAT( 7 ) ++ << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) ++ << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) ++ << section << " " << DUMP_STR_FORMAT( 1 ) << name << " " ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_HEX_FORMAT( 16 ) << value << " " ++ << DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 ) ++ << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) ++ << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) ++ << section << " " << std::endl ++ << " " << DUMP_STR_FORMAT( 1 ) << name << " " ++ << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void notes( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half no = reader.sections.size(); ++ for ( Elf_Half i = 0; i < no; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_NOTE == sec->get_type() ) { // Look at notes ++ note_section_accessor notes( reader, sec ); ++ Elf_Word no_notes = notes.get_notes_num(); ++ if ( no > 0 ) { ++ out << "Note section (" << sec->get_name() << ")" ++ << std::endl ++ << " No Type Name" << std::endl; ++ for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes ++ Elf_Word type; ++ std::string name; ++ void* desc; ++ Elf_Word descsz; ++ ++ if ( notes.get_note( j, type, name, desc, descsz ) ) { ++ // 'name' usually contains \0 at the end. Try to fix it ++ name = name.c_str(); ++ note( out, j, type, name ); ++ } ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void modinfo( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half no = reader.sections.size(); ++ for ( Elf_Half i = 0; i < no; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( ".modinfo" == sec->get_name() ) { // Look for the section ++ out << "Section .modinfo" << std::endl; ++ ++ const_modinfo_section_accessor modinfo( sec ); ++ for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) { ++ std::string field; ++ std::string value; ++ if ( modinfo.get_attribute( i, field, value ) ) { ++ out << " " << std::setw( 20 ) << field ++ << std::setw( 0 ) << " = " << value << std::endl; ++ } ++ } ++ ++ out << std::endl; ++ break; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void ++ note( std::ostream& out, int no, Elf_Word type, const std::string& name ) ++ { ++ out << " [" << DUMP_DEC_FORMAT( 2 ) << no << "] " ++ << DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 ) ++ << name << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void dynamic_tags( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_DYNAMIC == sec->get_type() ) { ++ dynamic_section_accessor dynamic( reader, sec ); ++ ++ Elf_Xword dyn_no = dynamic.get_entries_num(); ++ if ( dyn_no > 0 ) { ++ out << "Dynamic section (" << sec->get_name() << ")" ++ << std::endl; ++ out << "[ Nr ] Tag Name/Value" << std::endl; ++ for ( Elf_Xword i = 0; i < dyn_no; ++i ) { ++ Elf_Xword tag = 0; ++ Elf_Xword value = 0; ++ std::string str; ++ dynamic.get_entry( i, tag, value, str ); ++ dynamic_tag( out, i, tag, value, str, ++ reader.get_class() ); ++ if ( DT_NULL == tag ) { ++ break; ++ } ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void dynamic_tag( std::ostream& out, ++ Elf_Xword no, ++ Elf_Xword tag, ++ Elf_Xword value, ++ std::string str, ++ unsigned int /*elf_class*/ ) ++ { ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; ++ if ( str.empty() ) { ++ out << DUMP_HEX_FORMAT( 16 ) << value << " "; ++ } ++ else { ++ out << DUMP_STR_FORMAT( 32 ) << str << " "; ++ } ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_data( std::ostream& out, const section* sec ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ out << sec->get_name() << std::endl; ++ const char* pdata = sec->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i; ++ for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++ ++i ) { ++ if ( i % 16 == 0 ) { ++ out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; ++ } ++ ++ out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); ++ ++ if ( i % 16 == 15 ) { ++ out << std::endl; ++ } ++ } ++ if ( i % 16 != 0 ) { ++ out << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_datas( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Section Data:" << std::endl; ++ ++ for ( Elf_Half i = 1; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( sec->get_type() == SHT_NOBITS ) { ++ continue; ++ } ++ section_data( out, sec ); ++ } ++ ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void ++ segment_data( std::ostream& out, Elf_Half no, const segment* seg ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ out << "Segment # " << no << std::endl; ++ const char* pdata = seg->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i; ++ for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++ ++i ) { ++ if ( i % 16 == 0 ) { ++ out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; ++ } ++ ++ out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); ++ ++ if ( i % 16 == 15 ) { ++ out << std::endl; ++ } ++ } ++ if ( i % 16 != 0 ) { ++ out << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_datas( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.segments.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Segment Data:" << std::endl; ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ segment* seg = reader.segments[i]; ++ segment_data( out, i, seg ); ++ } ++ ++ out << std::endl; ++ } ++ ++ private: ++ //------------------------------------------------------------------------------ ++ template <typename T, typename K> ++ std::string static find_value_in_table( const T& table, const K& key ) ++ { ++ std::string res = "?"; ++ for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] ); ++ ++i ) { ++ if ( table[i].key == key ) { ++ res = table[i].str; ++ break; ++ } ++ } ++ ++ return res; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <typename T, typename K> ++ static std::string format_assoc( const T& table, const K& key ) ++ { ++ std::string str = find_value_in_table( table, key ); ++ if ( str == "?" ) { ++ std::ostringstream oss; ++ oss << str << " (0x" << std::hex << key << ")"; ++ str = oss.str(); ++ } ++ ++ return str; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <typename T> ++ static std::string format_assoc( const T& table, const char key ) ++ { ++ return format_assoc( table, (const int)key ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static std::string section_flags( Elf_Xword flags ) ++ { ++ std::string ret = ""; ++ if ( flags & SHF_WRITE ) { ++ ret += "W"; ++ } ++ if ( flags & SHF_ALLOC ) { ++ ret += "A"; ++ } ++ if ( flags & SHF_EXECINSTR ) { ++ ret += "X"; ++ } ++ ++ return ret; ++ } ++ ++//------------------------------------------------------------------------------ ++#define STR_FUNC_TABLE( name ) \ ++ template <typename T> static std::string str_##name( const T key ) \ ++ { \ ++ return format_assoc( name##_table, key ); \ ++ } ++ ++ STR_FUNC_TABLE( class ) ++ STR_FUNC_TABLE( endian ) ++ STR_FUNC_TABLE( version ) ++ STR_FUNC_TABLE( type ) ++ STR_FUNC_TABLE( machine ) ++ STR_FUNC_TABLE( section_type ) ++ STR_FUNC_TABLE( segment_type ) ++ STR_FUNC_TABLE( segment_flag ) ++ STR_FUNC_TABLE( symbol_bind ) ++ STR_FUNC_TABLE( symbol_type ) ++ STR_FUNC_TABLE( dynamic_tag ) ++ ++#undef STR_FUNC_TABLE ++#undef DUMP_DEC_FORMAT ++#undef DUMP_HEX_FORMAT ++#undef DUMP_STR_FORMAT ++}; // class dump ++ ++}; // namespace ELFIO ++ ++#endif // ELFIO_DUMP_HPP ++ ++/*** End of inlined file: elfio_dump.hpp ***/ ++ +diff --git a/tests/kt-test-utils/cpp-stub/stub.h b/tests/kt-test-utils/cpp-stub/stub.h +new file mode 100644 +index 0000000..c5f2f53 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/stub.h +@@ -0,0 +1,360 @@ ++#ifndef __STUB_H__ ++#define __STUB_H__ ++ ++#ifdef _WIN32 ++//windows ++#include <windows.h> ++#include <processthreadsapi.h> ++#else ++//linux ++#include <unistd.h> ++#include <bits/stdint-uintn.h> ++#include <sys/mman.h> ++#endif ++//c ++#include <cstddef> ++#include <cstring> ++//c++ ++#include <map> ++ ++ ++#define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME) ++ ++/********************************************************** ++ replace function ++**********************************************************/ ++#ifdef _WIN32 ++#define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size) ++#else ++#define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) ++#endif ++ ++#if defined(__aarch64__) || defined(_M_ARM64) ++ #define CODESIZE 16U ++ #define CODESIZE_MIN 16U ++ #define CODESIZE_MAX CODESIZE ++ // ldr x9, +8 ++ // br x9 ++ // addr ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t*)fn)[0] = 0x58000040 | 9;\ ++ ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\ ++ *(long long *)(fn + 8) = (long long )fn_stub;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__arm__) || defined(_M_ARM) ++ #define CODESIZE 8U ++ #define CODESIZE_MIN 8U ++ #define CODESIZE_MAX CODESIZE ++ // ldr pc, [pc, #-4] ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t*)fn)[0] = 0xe51ff004;\ ++ ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__mips64) ++ #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) ++ #define CODESIZE 80U ++ #define CODESIZE_MIN 80U ++ #define CODESIZE_MAX CODESIZE ++ //mips没有PC指针,所以需要手动入栈出栈 ++ //120000ce0: 67bdffe0 daddiu sp, sp, -32 //入栈 ++ //120000ce4: ffbf0018 sd ra, 24(sp) ++ //120000ce8: ffbe0010 sd s8, 16(sp) ++ //120000cec: ffbc0008 sd gp, 8(sp) ++ //120000cf0: 03a0f025 move s8, sp ++ ++ //120000d2c: 03c0e825 move sp, s8 //出栈 ++ //120000d30: dfbf0018 ld ra, 24(sp) ++ //120000d34: dfbe0010 ld s8, 16(sp) ++ //120000d38: dfbc0008 ld gp, 8(sp) ++ //120000d3c: 67bd0020 daddiu sp, sp, 32 ++ //120000d40: 03e00008 jr ra ++ ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t *)fn)[0] = 0x67bdffe0;\ ++ ((uint32_t *)fn)[1] = 0xffbf0018;\ ++ ((uint32_t *)fn)[2] = 0xffbe0010;\ ++ ((uint32_t *)fn)[3] = 0xffbc0008;\ ++ ((uint32_t *)fn)[4] = 0x03a0f025;\ ++ *(uint16_t *)(fn + 20) = (long long)fn_stub >> 32;\ ++ *(fn + 22) = 0x19;\ ++ *(fn + 23) = 0x24;\ ++ ((uint32_t *)fn)[6] = 0x0019cc38;\ ++ *(uint16_t *)(fn + 28) = (long long)fn_stub >> 16;\ ++ *(fn + 30) = 0x39;\ ++ *(fn + 31) = 0x37;\ ++ ((uint32_t *)fn)[8] = 0x0019cc38;\ ++ *(uint16_t *)(fn + 36) = (long long)fn_stub;\ ++ *(fn + 38) = 0x39;\ ++ *(fn + 39) = 0x37;\ ++ ((uint32_t *)fn)[10] = 0x0320f809;\ ++ ((uint32_t *)fn)[11] = 0x00000000;\ ++ ((uint32_t *)fn)[12] = 0x00000000;\ ++ ((uint32_t *)fn)[13] = 0x03c0e825;\ ++ ((uint32_t *)fn)[14] = 0xdfbf0018;\ ++ ((uint32_t *)fn)[15] = 0xdfbe0010;\ ++ ((uint32_t *)fn)[16] = 0xdfbc0008;\ ++ ((uint32_t *)fn)[17] = 0x67bd0020;\ ++ ((uint32_t *)fn)[18] = 0x03e00008;\ ++ ((uint32_t *)fn)[19] = 0x00000000;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__thumb__) || defined(_M_THUMB) ++ #error "Thumb is not supported" ++#else //__i386__ _x86_64__ ++ #define CODESIZE 13U ++ #define CODESIZE_MIN 5U ++ #define CODESIZE_MAX CODESIZE ++ //13 byte(jmp m16:64) ++ //movabs $0x102030405060708,%r11 ++ //jmpq *%r11 ++ static void REPLACE_FAR(void *t, char *fn, char *fn_stub) ++ { ++ *fn = 0x49; ++ *(fn + 1) = 0xbb; ++ *(long long *)(fn + 2) = (long long)fn_stub; ++ *(fn + 10) = 0x41; ++ *(fn + 11) = 0xff; ++ *(fn + 12) = 0xe3; ++ CACHEFLUSH((char *)fn, CODESIZE); ++ } ++ //5 byte(jmp rel32) ++ #define REPLACE_NEAR(t, fn, fn_stub)\ ++ *fn = 0xE9;\ ++ *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++#endif ++ ++struct func_stub ++{ ++ char *fn; ++ unsigned char code_buf[CODESIZE]; ++ bool far_jmp; ++}; ++ ++class Stub ++{ ++public: ++ Stub() ++ { ++#ifdef _WIN32 ++ SYSTEM_INFO sys_info; ++ GetSystemInfo(&sys_info); ++ m_pagesize = sys_info.dwPageSize; ++#else ++ m_pagesize = sysconf(_SC_PAGE_SIZE); ++#endif ++ ++ if (m_pagesize < 0) ++ { ++ m_pagesize = 4096; ++ } ++ } ++ ~Stub() ++ { ++ clear(); ++ } ++ ++ virtual void clear() ++ { ++ std::map<char*,func_stub*>::iterator iter; ++ struct func_stub *pstub; ++ for(iter=m_result.begin(); iter != m_result.end(); iter++) ++ { ++ pstub = iter->second; ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ ++ if(pstub->far_jmp) ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); ++ } ++ else ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); ++ } ++ ++#ifdef _WIN32 ++ VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect); ++#else ++ CACHEFLUSH(pstub->fn,CODESIZE); ++ mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC); ++#endif ++ } ++ ++ iter->second = NULL; ++ delete pstub; ++ } ++ ++ m_result.clear(); ++ return; ++ } ++ template<typename T,typename S> ++ bool set(T addr, S addr_stub) ++ { ++ char * fn; ++ char * fn_stub; ++ fn = addrof(addr); ++ fn_stub = addrof(addr_stub); ++ struct func_stub *pstub; ++ std::map<char*,func_stub*>::iterator iter = m_result.find(fn); ++ ++ if (iter == m_result.end()) ++ { ++ pstub = new func_stub; ++ //start ++ pstub->fn = fn; ++ ++ if(distanceof(fn, fn_stub)) ++ { ++ pstub->far_jmp = true; ++ std::memcpy(pstub->code_buf, fn, CODESIZE_MAX); ++ } ++ else ++ { ++ pstub->far_jmp = false; ++ std::memcpy(pstub->code_buf, fn, CODESIZE_MIN); ++ } ++ } ++ else { ++ pstub = iter->second; ++ pstub->far_jmp = distanceof(fn, fn_stub); ++ } ++ ++ ++ ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), static_cast<size_t>(m_pagesize * 2), PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ throw("stub set memory protect to w+r+x faild"); ++ return false; ++ } ++ ++ if(pstub->far_jmp) ++ { ++ REPLACE_FAR(this, fn, fn_stub); ++ } ++ else ++ { ++ REPLACE_NEAR(this, fn, fn_stub); ++ } ++ ++ ++#ifdef _WIN32 ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) ++#endif ++ { ++ throw("stub set memory protect to r+x failed"); ++ return false; ++ } ++ m_result.insert(std::pair<char*,func_stub*>(fn,pstub)); ++ return true; ++ } ++ ++ template<typename T> ++ bool reset(T addr) ++ { ++ char * fn; ++ fn = addrof(addr); ++ ++ std::map<char*,func_stub*>::iterator iter = m_result.find(fn); ++ ++ if (iter == m_result.end()) ++ { ++ return true; ++ } ++ struct func_stub *pstub; ++ pstub = iter->second; ++ ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ throw("stub reset memory protect to w+r+x faild"); ++ return false; ++ } ++ ++ if(pstub->far_jmp) ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); ++ } ++ else ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); ++ } ++ ++#ifdef _WIN32 ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) ++#else ++ CACHEFLUSH(pstub->fn,CODESIZE); ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) ++#endif ++ { ++ throw("stub reset memory protect to r+x failed"); ++ return false; ++ } ++ ++ m_result.erase(iter); ++ delete pstub; ++ ++ return true; ++ } ++protected: ++ char *pageof(char* addr) ++ { ++#ifdef _WIN32 ++ return (char *)((unsigned long long)addr & ~(m_pagesize - 1)); ++#else ++ return (char *)((unsigned long)addr & ~(m_pagesize - 1)); ++#endif ++ } ++ ++ template<typename T> ++ char* addrof(T addr) ++ { ++ union ++ { ++ T _s; ++ char* _d; ++ }ut; ++ ut._s = addr; ++ return ut._d; ++ } ++ ++ bool distanceof(char* addr, char* addr_stub) ++ { ++ std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub; ++ if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0)) ++ { ++ return true; ++ } ++ return false; ++ } ++ ++protected: ++#ifdef _WIN32 ++ //LLP64 ++ long long m_pagesize; ++#else ++ //LP64 ++ long m_pagesize; ++#endif ++ std::map<char*, func_stub*> m_result; ++}; ++ ++#endif +diff --git a/tests/unit_test_account_helper/CMakeLists.txt b/tests/unit_test_account_helper/CMakeLists.txt +new file mode 100644 +index 0000000..6ed7b7e +--- /dev/null ++++ b/tests/unit_test_account_helper/CMakeLists.txt +@@ -0,0 +1,64 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/accountshelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ unit_test_account_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/dbusifs/accountshelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_account_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_account_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_account_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_account_helper/main.cpp b/tests/unit_test_account_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_account_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_account_helper/unit_test_account_helper.cpp b/tests/unit_test_account_helper/unit_test_account_helper.cpp +new file mode 100644 +index 0000000..d7a71b6 +--- /dev/null ++++ b/tests/unit_test_account_helper/unit_test_account_helper.cpp +@@ -0,0 +1,65 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/accountshelper.h" ++ ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class AccountsHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pAccountsHelperDbus = new AccountsHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pAccountsHelperDbus; ++ m_pAccountsHelperDbus = nullptr; ++ } ++ ++ static AccountsHelper *m_pAccountsHelperDbus; ++}; ++ ++AccountsHelper *AccountsHelperTest::m_pAccountsHelperDbus = nullptr; ++ ++TEST_F(AccountsHelperTest, UserLanguageByName) ++{ ++ QString value = m_pAccountsHelperDbus->getUserLanguageByName(getenv("USER")); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_STREQ(cstr, "zh_CN"); ++} ++ ++TEST_F(AccountsHelperTest, UserBackgroundByName) ++{ ++ QString value = m_pAccountsHelperDbus->getUserBackgroundByName(getenv("USER")); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_STREQ(cstr, "zh_CN"); ++} ++ ++TEST_F(AccountsHelperTest, UserSessionByName) ++{ ++ QString value = m_pAccountsHelperDbus->getUserSessionByName(getenv("USER")); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_STREQ(cstr, "zh_CN"); ++} ++ ++TEST_F(AccountsHelperTest, AccountBackground) ++{ ++ QString value = m_pAccountsHelperDbus->getAccountBackground(1000); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_STREQ(cstr, "zh_CN"); ++} ++ ++TEST_F(AccountsHelperTest, UserList) ++{ ++ QStringList value = m_pAccountsHelperDbus->getUserList(); ++ ASSERT_EQ(value.isEmpty(), false); ++} +diff --git a/tests/unit_test_auth_pam/CMakeLists.txt b/tests/unit_test_auth_pam/CMakeLists.txt +new file mode 100644 +index 0000000..2cb1403 +--- /dev/null ++++ b/tests/unit_test_auth_pam/CMakeLists.txt +@@ -0,0 +1,86 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus Test REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量 ++find_library(PAM_LIBRARIES pam) ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/authpamthread.cpp ++ ../../src/lock-backend/pamauthenticate.cpp ++ ../../src/lock-backend/lightdmhelper.cpp ++ ../../src/dbusifs/accountshelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/dbusifs/uniauthservice.cpp ++ ../../src/lock-backend/securityuser.cpp ++ ../../src/dbusifs/freedesktophelper.cpp ++ unit_test_auth_pam.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/authpamthread.h ++ ../../src/lock-backend/pamauthenticate.h ++ ../../src/lock-backend/lightdmhelper.h ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/dbusifs/accountshelper.h ++ ../../src/common/configuration.h ++ ../../src/dbusifs/uniauthservice.h ++ ../../src/lock-backend/securityuser.h ++ ../../src/dbusifs/freedesktophelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${Qt5Test_INCLUDE_DIRS} ++ ${LIGHTDM-QT5-3_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_auth_pam ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_auth_pam ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::Test ++ ${QGS_LIBRARIES} ++ ${PAM_LIBRARIES} ++ ${LIGHTDM-QT5-3_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_auth_pam ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_auth_pam/main.cpp b/tests/unit_test_auth_pam/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_auth_pam/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_auth_pam/unit_test_auth_pam.cpp b/tests/unit_test_auth_pam/unit_test_auth_pam.cpp +new file mode 100644 +index 0000000..f88a413 +--- /dev/null ++++ b/tests/unit_test_auth_pam/unit_test_auth_pam.cpp +@@ -0,0 +1,377 @@ ++#include <gtest/gtest.h> ++#include <memory> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <string.h> ++#include <security/pam_appl.h> ++#include <gtest/gtest.h> ++#include <QCoreApplication> ++#include <QLightDM/Greeter> ++#include <QSocketNotifier> ++#include <QDebug> ++#include <QSignalSpy> ++#include "../../src/dbusifs/accountshelper.h" ++#include "../../src/lock-backend/authpamthread.h" ++#include "../../src/lock-backend/pamauthenticate.h" ++#include "../../src/lock-backend/lightdmhelper.h" ++ ++class AuthPamThreadTest : public ::testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pAuthPamThreadDbus = new AuthPamThread(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pAuthPamThreadDbus; ++ m_pAuthPamThreadDbus = nullptr; ++ } ++ ++ static AuthPamThread *m_pAuthPamThreadDbus; ++ ++ // 辅助函数,模拟文件描述符操作 ++ int createMockPipe() ++ { ++ int fds[2]; ++ if (pipe(fds) == -1) { ++ return -1; ++ } ++ return fds[0]; ++ } ++ ++ // 辅助函数,模拟写入数据到文件描述符 ++ void writeToFd(int fd, const char *data) ++ { ++ write(fd, data, strlen(data)); ++ } ++ ++ // 辅助函数,从文件描述符读取数据 ++ std::string readFromFd(int fd) ++ { ++ char buffer[1024]; ++ ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1); ++ if (bytesRead > 0) { ++ buffer[bytesRead] = '\0'; ++ return buffer; ++ } ++ return ""; ++ } ++ ++ // 辅助函数,模拟 pam_start 的返回结果 ++ int mockPamStart(pam_handle_t **pamh, const char *service, const char *user, const struct pam_conv *conv) ++ { ++ *pamh = reinterpret_cast<pam_handle_t *>(1); ++ return PAM_SUCCESS; ++ } ++ ++ // 辅助函数,模拟 pam_authenticate 的返回结果 ++ int mockPamAuthenticate(pam_handle_t *pamh, int flags) ++ { ++ return PAM_SUCCESS; ++ } ++ ++ // 辅助函数,模拟 pam_acct_mgmt 的返回结果 ++ int mockPamAcctMgmt(pam_handle_t *pamh, int flags) ++ { ++ return PAM_SUCCESS; ++ } ++ ++ // 辅助函数,模拟 pam_get_item 的返回结果 ++ int mockPamGetItem(pam_handle_t *pamh, int item_type, const void **item) ++ { ++ *item = nullptr; ++ return PAM_SUCCESS; ++ } ++ ++ // 辅助函数,模拟 pam_strerror 的返回结果 ++ const char *mockPamStrerror(pam_handle_t *pamh, int pam_err) ++ { ++ return "Mock Error"; ++ } ++ ++ // 辅助函数,模拟 pam_end 的行为 ++ int mockPamEnd(pam_handle_t *pamh, int pam_status) ++ { ++ return PAM_SUCCESS; ++ } ++}; ++AuthPamThread *AuthPamThreadTest::m_pAuthPamThreadDbus = nullptr; ++ ++// 测试 _authenticate 函数 ++TEST_F(AuthPamThreadTest, Authenticate) ++{ ++ m_pAuthPamThreadDbus->m_strUserName = getenv("USER"); ++ qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; ++ ++ // 模拟 pam 函数 ++ auto originalPamStart = pam_start; ++ auto originalPamAuthenticate = pam_authenticate; ++ auto originalPamAcctMgmt = pam_acct_mgmt; ++ auto originalPamGetItem = pam_get_item; ++ auto originalPamStrerror = pam_strerror; ++ auto originalPamEnd = pam_end; ++ ++ // pam_start = mockPamStart; ++ // pam_authenticate = mockPamAuthenticate; ++ // pam_acct_mgmt = mockPamAcctMgmt; ++ // pam_get_item = mockPamGetItem; ++ // pam_strerror = mockPamStrerror; ++ // pam_end = mockPamEnd; ++ ++ qDebug() << "??????????????????????????????????????"; ++ // m_pAuthPamThreadDbus->_authenticate(m_pAuthPamThreadDbus->m_strUserName.toLocal8Bit().data()); ++ ++ // 恢复原始函数 ++ // pam_start = originalPamStart; ++ // pam_authenticate = originalPamAuthenticate; ++ // pam_acct_mgmt = originalPamAcctMgmt; ++ // pam_get_item = originalPamGetItem; ++ // pam_strerror = originalPamStrerror; ++ // pam_end = originalPamEnd; ++} ++ ++// 测试 startAuthPam 函数 ++TEST_F(AuthPamThreadTest, StartAuthPam) ++{ ++ qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; ++ int fdRead = createMockPipe(); ++ int fdWrite = createMockPipe(); ++ ++ m_pAuthPamThreadDbus->startAuthPam(fdRead, fdWrite, getenv("USER")); ++ ++ EXPECT_TRUE(m_pAuthPamThreadDbus->isRunning()); ++ ++ close(fdRead); ++ close(fdWrite); ++} ++ ++// 测试 run 函数 ++TEST_F(AuthPamThreadTest, Run) ++{ ++ ++ int fdRead = createMockPipe(); ++ int fdWrite = createMockPipe(); ++ ++ m_pAuthPamThreadDbus->m_fdRead = fdRead; ++ m_pAuthPamThreadDbus->m_fdWrite = fdWrite; ++ m_pAuthPamThreadDbus->m_strUserName = getenv("USER"); ++ ++ // m_pAuthPamThreadDbus->run(); ++ ++ close(fdRead); ++ close(fdWrite); ++} ++ ++// 测试 stopAuthPam 函数 ++TEST_F(AuthPamThreadTest, StopAuthPam) ++{ ++ m_pAuthPamThreadDbus->startAuthPam(0, 0, getenv("USER")); ++ ++ m_pAuthPamThreadDbus->stopAuthPam(); ++ ++ EXPECT_FALSE(m_pAuthPamThreadDbus->isRunning()); ++} ++ ++// 测试 PamAuthenticate 类 ++class PamAuthenticateTest : public ::testing::Test ++{ ++protected: ++ static AuthPamThread *m_pAuthPamThreadDbus; ++ ++ QSharedPointer<LightDMHelper> lightDMHelper; ++ QSharedPointer<PamAuthenticate> pamAuthenticate; ++ ++ void SetUp() override ++ { ++ lightDMHelper = QSharedPointer<LightDMHelper>( ++ new LightDMHelper(QSharedPointer<AccountsHelper>(new AccountsHelper(nullptr)), nullptr)); ++ pamAuthenticate = QSharedPointer<PamAuthenticate>(new PamAuthenticate(lightDMHelper)); ++ } ++ ++ void TearDown() override ++ { ++ pamAuthenticate.reset(); ++ lightDMHelper.reset(); ++ } ++ ++ // 辅助函数,模拟 QSocketNotifier 的 activated 信号 ++ void simulateSocketNotifierActivated(QSocketNotifier *socketNotifier) ++ { ++ // Q_EMIT socketNotifier->activated(socketNotifier->socket()); ++ } ++ ++ // 辅助函数,模拟管道操作 ++ int createMockPipe() ++ { ++ int fds[2]; ++ if (pipe(fds) == -1) { ++ return -1; ++ } ++ return fds[0]; ++ } ++ ++ // 辅助函数,模拟 AuthPamThread 的行为 ++ class MockAuthPamThread : public AuthPamThread ++ { ++ public: ++ }; ++ ++ // 辅助函数,模拟 LightDMHelper 的行为 ++ class MockLightDMHelper : public LightDMHelper ++ { ++ public: ++ MockLightDMHelper() ++ : LightDMHelper(QSharedPointer<AccountsHelper>(new AccountsHelper(nullptr)), nullptr, nullptr) ++ { ++ } ++ }; ++}; ++ ++// 测试 PamAuthenticate 构造函数 ++TEST_F(PamAuthenticateTest, Constructor) ++{ ++ // 检查信号和槽的连接 ++ // EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(showMessage(QString, ++ // QLightDM::Greeter::MessageType)), ++ // pamAuthenticate.get(), SLOT(onLDMShowMessage(QString, QLightDM::Greeter::MessageType))); ++ ++ // EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), ++ // pamAuthenticate.get(), SLOT(onLDMShowPrompt(QString, QLightDM::Greeter::PromptType))); ++ ++ // EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(authenticationComplete()), ++ // pamAuthenticate.get(), SIGNAL(authenticationComplete())); ++} ++ ++// 测试 inAuthentication 函数 ++TEST_F(PamAuthenticateTest, InAuthentication) ++{ ++ // 测试 m_isOtherUser 为 false 时的情况 ++ EXPECT_FALSE(pamAuthenticate->inAuthentication()); ++ // 测试 m_isOtherUser 为 true 时的情况 ++ pamAuthenticate->m_isOtherUser = true; ++ EXPECT_FALSE(pamAuthenticate->inAuthentication()); ++} ++ ++// 测试 isAuthenticated 函数 ++TEST_F(PamAuthenticateTest, IsAuthenticated) ++{ ++ // 测试 m_isOtherUser 为 false 时的情况 ++ EXPECT_FALSE(pamAuthenticate->isAuthenticated()); ++ ++ // 测试 m_isOtherUser 为 true 时的情况 ++ pamAuthenticate->m_isOtherUser = true; ++ EXPECT_FALSE(pamAuthenticate->isAuthenticated()); ++} ++ ++// 测试 authenticationUser 函数 ++TEST_F(PamAuthenticateTest, AuthenticationUser) ++{ ++ // 测试 m_isOtherUser 为 false 时的情况 ++ EXPECT_EQ(pamAuthenticate->authenticationUser(), ""); ++ ++ // 测试 m_isOtherUser 为 true 时的情况 ++ pamAuthenticate->m_isOtherUser = true; ++ EXPECT_EQ(pamAuthenticate->authenticationUser(), ""); ++} ++ ++// 测试 authenticate 函数 ++TEST_F(PamAuthenticateTest, Authenticate) ++{ ++ // 测试普通用户的情况 ++ pamAuthenticate->authenticate("testuser"); ++ EXPECT_EQ(pamAuthenticate->m_strUserName, "testuser"); ++ EXPECT_NE(pamAuthenticate->m_threadAuthPam, nullptr); ++ EXPECT_NE(pamAuthenticate->m_socketNotifier, nullptr); ++ ++ // 测试访客用户的情况 ++ pamAuthenticate->authenticate("*guest"); ++ ++ // 测试 m_isOtherUser 为 true 的情况 ++ pamAuthenticate->m_isOtherUser = true; ++ pamAuthenticate->authenticate("otheruser"); ++} ++ ++// 测试 respond 函数 ++TEST_F(PamAuthenticateTest, Respond) ++{ ++ // 测试正常响应的情况 ++ pamAuthenticate->m_nPrompts = 1; ++ pamAuthenticate->respond("response"); ++ EXPECT_EQ(pamAuthenticate->m_responseList.size(), 1); ++ ++ // 测试 m_nPrompts 为 0 的情况 ++ pamAuthenticate->m_nPrompts = 0; ++ pamAuthenticate->m_isOtherUser = false; ++ pamAuthenticate->respond("response"); ++ EXPECT_EQ(pamAuthenticate->m_responseList.size(), 1); ++} ++ ++// 测试 cancelAuthentication 函数 ++TEST_F(PamAuthenticateTest, CancelAuthentication) ++{ ++ // 模拟 AuthPamThread 和 QSocketNotifier ++ pamAuthenticate->m_threadAuthPam = new MockAuthPamThread(); ++ pamAuthenticate->m_socketNotifier = new QSocketNotifier(0, QSocketNotifier::Read); ++ ++ pamAuthenticate->m_isOtherUser = false; ++ pamAuthenticate->cancelAuthentication(); ++ ++ EXPECT_EQ(pamAuthenticate->m_threadAuthPam, nullptr); ++ EXPECT_EQ(pamAuthenticate->m_socketNotifier, nullptr); ++ EXPECT_FALSE(pamAuthenticate->m_isAuthenticated); ++ EXPECT_FALSE(pamAuthenticate->m_isInAuthentication); ++ EXPECT_EQ(pamAuthenticate->m_messageList.size(), 0); ++ EXPECT_EQ(pamAuthenticate->m_responseList.size(), 0); ++ EXPECT_EQ(pamAuthenticate->m_nPrompts, 0); ++} ++ ++// 测试 onSockRead 函数 ++TEST_F(PamAuthenticateTest, OnSockRead) ++{ ++ // 模拟管道 ++ int fdToParent[2]; ++ if (pipe(fdToParent) == -1) { ++ FAIL() << "Failed to create pipe"; ++ } ++ ++ pamAuthenticate->m_fdToParent[0] = fdToParent[0]; ++ ++ // 测试认证完成的情况 ++ int authComplete = 1; ++ int authRet = PAM_SUCCESS; ++ write(pamAuthenticate->m_fdToParent[0], &authComplete, sizeof(authComplete)); ++ write(pamAuthenticate->m_fdToParent[0], &authRet, sizeof(authRet)); ++ ++ QSignalSpy authenticationCompleteSpy(pamAuthenticate.get(), SIGNAL(authenticationComplete())); ++ ++ simulateSocketNotifierActivated(pamAuthenticate->m_socketNotifier); ++ ++ EXPECT_EQ(pamAuthenticate->m_isAuthenticated, true); ++ EXPECT_EQ(authenticationCompleteSpy.count(), 1); ++ ++ // 测试消息接收的情况 ++ authComplete = 0; ++ int msgLength = 1; ++ write(pamAuthenticate->m_fdToParent[0], &authComplete, sizeof(authComplete)); ++ write(pamAuthenticate->m_fdToParent[0], &msgLength, sizeof(msgLength)); ++ ++ struct pam_message message; ++ message.msg_style = PAM_PROMPT_ECHO_OFF; ++ message.msg = "Enter password"; ++ ++ write(pamAuthenticate->m_fdToParent[0], &message.msg_style, sizeof(message.msg_style)); ++ write(pamAuthenticate->m_fdToParent[0], message.msg, strlen(message.msg) + 1); ++ ++ QSignalSpy showPromptSpy(pamAuthenticate.get(), SIGNAL(showPrompt(QString, PamAuth::PromptType))); ++ ++ simulateSocketNotifierActivated(pamAuthenticate->m_socketNotifier); ++ ++ EXPECT_EQ(showPromptSpy.count(), 1); ++ ++ close(fdToParent[0]); ++ close(fdToParent[1]); ++} +diff --git a/tests/unit_test_backend_dbus/CMakeLists.txt b/tests/unit_test_backend_dbus/CMakeLists.txt +new file mode 100644 +index 0000000..9a6be89 +--- /dev/null ++++ b/tests/unit_test_backend_dbus/CMakeLists.txt +@@ -0,0 +1,68 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-dialog/backenddbushelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/agreementinfo.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/common/global_utils.cpp ++ unit_test_backend_dbus.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-dialog/backenddbushelper.h ++ ../../src/common/definetypes.h ++ ../../src/common/biodefines.h ++ ../../src/userinfo.h ++ ../../src/agreementinfo.h ++ ../../src/common/global_utils.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_backend_dbus ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_backend_dbus ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_backend_dbus ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_backend_dbus/main.cpp b/tests/unit_test_backend_dbus/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_backend_dbus/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp b/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp +new file mode 100644 +index 0000000..6e5d1a1 +--- /dev/null ++++ b/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp +@@ -0,0 +1,423 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/lock-dialog/backenddbushelper.h" ++#include "../../src/common/definetypes.h" ++#include "../../src/agreementinfo.h" ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class BackendDbusHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_"); ++ QString sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum); ++ m_pBackendDbusHelperDbus = new BackendDbusHelper(sessionDbus, SS_DBUS_PATH, QDBusConnection::sessionBus()); ++ if (!m_pBackendDbusHelperDbus->isValid()) { ++ delete m_pBackendDbusHelperDbus; ++ m_pBackendDbusHelperDbus = new BackendDbusHelper(SS_DBUS_SERVICE, SS_DBUS_PATH, QDBusConnection::sessionBus()); ++ } ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pBackendDbusHelperDbus; ++ m_pBackendDbusHelperDbus = nullptr; ++ } ++ ++ static BackendDbusHelper *m_pBackendDbusHelperDbus; ++}; ++ ++BackendDbusHelper *BackendDbusHelperTest::m_pBackendDbusHelperDbus = nullptr; ++ ++TEST_F(BackendDbusHelperTest, getUsersInfo) ++{ ++ QList<UserInfoPtr> value = m_pBackendDbusHelperDbus->getUsersInfo(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, getAgreementInfo) ++{ ++ AgreementInfoPtr value = m_pBackendDbusHelperDbus->getAgreementInfo(); ++// ASSERT_EQ(value, NULL); ++} ++ ++TEST_F(BackendDbusHelperTest, getSessionsInfo) ++{ ++ QList<QString> value = m_pBackendDbusHelperDbus->getSessionsInfo(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, getBatteryArgs) ++{ ++ QStringList value = m_pBackendDbusHelperDbus->getBatteryArgs(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, getSleepLockcheck) ++{ ++ QStringList value = m_pBackendDbusHelperDbus->getSleepLockcheck(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, isSessionActive) ++{ ++ bool value = m_pBackendDbusHelperDbus->isSessionActive(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, switchToUser) ++{ ++ int value = m_pBackendDbusHelperDbus->switchToUser(getenv("USER")); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BackendDbusHelperTest, setCurrentUser) ++{ ++ bool value = m_pBackendDbusHelperDbus->setCurrentUser(getenv("USER")); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, setPowerManager) ++{ ++ bool value = m_pBackendDbusHelperDbus->setPowerManager("LockScreen"); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, sendPassword) ++{ ++ QByteArray decryptText; ++ bool value = m_pBackendDbusHelperDbus->sendPassword(getenv("USER"), decryptText); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, getBatteryIconName) ++{ ++ QString value = m_pBackendDbusHelperDbus->getBatteryIconName(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, getIsBattery) ++{ ++ bool value = m_pBackendDbusHelperDbus->getIsBattery(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, getCurTabletMode) ++{ ++ bool value = m_pBackendDbusHelperDbus->getCurTabletMode(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, lockStateChanged) ++{ ++ bool value = m_pBackendDbusHelperDbus->lockStateChanged(false, false); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, pamIsInAuthentication) ++{ ++ m_pBackendDbusHelperDbus->startSession(); ++ m_pBackendDbusHelperDbus->pamAuthenticate(getenv("USER")); ++ m_pBackendDbusHelperDbus->bioStartAuth(getuid(), 32); ++ m_pBackendDbusHelperDbus->bioStopAuth(); ++ m_pBackendDbusHelperDbus->pamRespond(""); ++ m_pBackendDbusHelperDbus->pamAuthenticateCancel(); ++ bool value = m_pBackendDbusHelperDbus->pamIsInAuthentication(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, pamIsAuthenticated) ++{ ++ bool value = m_pBackendDbusHelperDbus->pamIsAuthenticated(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, pamAuthenticateUser) ++{ ++ QString value = m_pBackendDbusHelperDbus->pamAuthenticateUser(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, bioGetAvailableDevices) ++{ ++ QList<DeviceInfo> value = m_pBackendDbusHelperDbus->bioGetAvailableDevices(101); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, bioGetDisabledDevices) ++{ ++ QList<int> value = m_pBackendDbusHelperDbus->bioGetDisabledDevices(101); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, bioGetBioAuthState) ++{ ++ int value = m_pBackendDbusHelperDbus->bioGetBioAuthState(); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BackendDbusHelperTest, bioGetCurBioInfo) ++{ ++ DeviceInfo bioValue1 = m_pBackendDbusHelperDbus->bioGetCurBioInfo(); ++ DeviceInfo bioValue2 = m_pBackendDbusHelperDbus->bioFindDeviceById(getuid(), 101); ++ DeviceInfo bioValue3 = m_pBackendDbusHelperDbus->bioFindDeviceByName(getuid(), "uru4000"); ++ QString value = m_pBackendDbusHelperDbus->bioGetDefaultDevice(getuid(), getenv("USER")); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, getCurrentSession) ++{ ++ QString value = m_pBackendDbusHelperDbus->getCurrentSession(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, setCurrentSession) ++{ ++ bool value = m_pBackendDbusHelperDbus->setCurrentSession("testSession"); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, onUpdateInformation) ++{ ++ QList<int> list{LOCK_CMD_ID_USERINFO_CHANGED, LOCK_CMD_ID_CURRENT_USER_CHANGED, ++ LOCK_CMD_ID_CURRENT_SESSION_CHANGED, LOCK_CMD_ID_LOGIN1_REQ_LOCK, ++ LOCK_CMD_ID_LOGIN1_REQ_UNLOCK, LOCK_CMD_ID_LOGIN1_PREPAREFORSLEEP, ++ LOCK_CMD_ID_LOGIN1_SESSION_ACTIVE_CHANGED, LOCK_CMD_ID_GSETTINGS_LOCKSCREEN_CONF_CHANGED, ++ LOCK_CMD_ID_GSETTINGS_SCREENSAVER_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_POWERMANAGER_CONF_CHANGED, ++ LOCK_CMD_ID_GSETTINGS_MATEBG_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_UKCCPLUGINS_CONF_CHANGED, ++ LOCK_CMD_ID_GSETTINGS_THEMESTYLE_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_SESSION_CONF_CHANGED, ++ LOCK_CMD_ID_LOGIN1_BLOCKINHIBITED_CHANGED, LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED, ++ LOCK_CMD_ID_PAMAUTH_SHOWMESSAGE, LOCK_CMD_ID_PAMAUTH_SHOWPROMPT, LOCK_CMD_ID_PAMAUTH_AUTH_COMPLETED, ++ LOCK_CMD_ID_GSETTINGS_USD_MEDIAKEYS_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_USD_MEDIA_STATE_KEYS_CONF_CHANGED, ++ LOCK_CMD_ID_UPOWER_BATTERY_STATUS, LOCK_CMD_ID_UPOWER_BATTERY, LOCK_CMD_ID_BIOAUTH_SERVICE_STATUS_CHANGED, ++ LOCK_CMD_ID_BIOAUTH_DEVICE_CHANGED, LOCK_CMD_ID_BIOAUTH_SHOW_MESSAGE, LOCK_CMD_ID_BIOAUTH_AUTHSTATE_CHANGED, ++ LOCK_CMD_ID_BIOAUTH_FRAME_DATA, LOCK_CMD_ID_BIOAUTH_COMPLETE, LOCK_CMD_ID_TABLET_MODE_CHANGED}; ++ for (int i = 0; i < list.count(); i++) { ++ QJsonObject retObj; ++ retObj["CmdId"] = list.at(i); ++ m_pBackendDbusHelperDbus->onUpdateInformation(QString(QJsonDocument(retObj).toJson())); ++ } ++} ++ ++TEST_F(BackendDbusHelperTest, usdExternalDoAction) ++{ ++ bool value = m_pBackendDbusHelperDbus->usdExternalDoAction(VOLUME_DOWN_KEY); ++ m_pBackendDbusHelperDbus->usdExternalDoAction(VOLUME_UP_KEY); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(BackendDbusHelperTest, getDefaultAuthUser) ++{ ++ QString value = m_pBackendDbusHelperDbus->getDefaultAuthUser(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, getCurrentUser) ++{ ++ QString value = m_pBackendDbusHelperDbus->getCurrentUser(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BackendDbusHelperTest, getScreenSaverConf) ++{ ++ bool value = m_pBackendDbusHelperDbus->getScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setScreenSaverConf) ++{ ++ bool oldvalue = m_pBackendDbusHelperDbus->getScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool(); ++ bool value = m_pBackendDbusHelperDbus->setScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, !oldvalue); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getLockScreenConf) ++{ ++ bool value = m_pBackendDbusHelperDbus->getLockScreenConf(KEY_LOCK_ENABLED).toBool(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setLockScreenConf) ++{ ++ bool oldvalue = m_pBackendDbusHelperDbus->getLockScreenConf(KEY_LOCK_ENABLED).toBool(); ++ bool value = m_pBackendDbusHelperDbus->setLockScreenConf(KEY_LOCK_ENABLED, !oldvalue); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setLockScreenConf(KEY_LOCK_ENABLED, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getShutdownLockcheck) ++{ ++ QStringList value = m_pBackendDbusHelperDbus->getShutdownLockcheck(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, getSaverThemes) ++{ ++ QStringList value = m_pBackendDbusHelperDbus->getSaverThemes(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerConf) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerConf(KEY_LOCK_BLANKSCREEN).toBool(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setPowerManagerConf) ++{ ++ bool oldvalue = m_pBackendDbusHelperDbus->getPowerManagerConf(KEY_LOCK_BLANKSCREEN).toBool(); ++ bool value = m_pBackendDbusHelperDbus->setPowerManagerConf(KEY_LOCK_BLANKSCREEN, !oldvalue); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setPowerManagerConf(KEY_LOCK_BLANKSCREEN, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getMateBgConf) ++{ ++ QString value = m_pBackendDbusHelperDbus->getMateBgConf(KEY_PICTURE_FILENAME).toString(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BackendDbusHelperTest, setMateBgConf) ++{ ++ QString oldvalue = m_pBackendDbusHelperDbus->getMateBgConf(KEY_PICTURE_FILENAME).toString(); ++ return ; ++ ++ bool value = m_pBackendDbusHelperDbus->setMateBgConf("picture-filename", "sss"); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setMateBgConf("picture-filename", oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getUkccPluginsConf) ++{ ++ QString value = m_pBackendDbusHelperDbus->getUkccPluginsConf(KEY_DATE).toString(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setUkccPluginsConf) ++{ ++ QString oldvalue = m_pBackendDbusHelperDbus->getUkccPluginsConf(KEY_DATE).toString(); ++ bool value = m_pBackendDbusHelperDbus->setUkccPluginsConf(KEY_DATE, "sss"); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setUkccPluginsConf(KEY_DATE, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getThemeStyleConf) ++{ ++ QString value = m_pBackendDbusHelperDbus->getThemeStyleConf(KEY_THEME_COLOR).toString(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setThemeStyleConf) ++{ ++ QString oldvalue = m_pBackendDbusHelperDbus->getThemeStyleConf(KEY_THEME_COLOR).toString(); ++ bool value = m_pBackendDbusHelperDbus->setThemeStyleConf(KEY_THEME_COLOR, "sss"); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setThemeStyleConf(KEY_THEME_COLOR, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getSessionConf) ++{ ++ int value = m_pBackendDbusHelperDbus->getSessionConf(KEY_SESSION_IDLE).toInt(); ++ ASSERT_EQ(value, 60); ++} ++ ++TEST_F(BackendDbusHelperTest, setSessionConf) ++{ ++ int oldvalue = m_pBackendDbusHelperDbus->getSessionConf(KEY_SESSION_IDLE).toInt(); ++ bool value = m_pBackendDbusHelperDbus->setSessionConf(KEY_SESSION_IDLE, 30); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setSessionConf(KEY_SESSION_IDLE, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getKeyboardConf) ++{ ++ bool value = m_pBackendDbusHelperDbus->getKeyboardConf(KEY_CAPSLOCK_STATUS).toBool(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, setKeyboardConf) ++{ ++ bool oldvalue = m_pBackendDbusHelperDbus->getKeyboardConf(KEY_CAPSLOCK_STATUS).toBool(); ++ bool value = m_pBackendDbusHelperDbus->setKeyboardConf(KEY_CAPSLOCK_STATUS, !oldvalue); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setKeyboardConf(KEY_CAPSLOCK_STATUS, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getUsdMediaStateKeys) ++{ ++ int value = m_pBackendDbusHelperDbus->getUsdMediaStateKeys(KEY_RFKILL_STATE).toInt(); ++ ASSERT_EQ(value, 60); ++} ++ ++TEST_F(BackendDbusHelperTest, setUsdMediaStateKeys) ++{ ++ int oldvalue = m_pBackendDbusHelperDbus->getUsdMediaStateKeys(KEY_RFKILL_STATE).toInt(); ++ bool value = m_pBackendDbusHelperDbus->setUsdMediaStateKeys(KEY_RFKILL_STATE, 0); ++ ASSERT_EQ(value, false); ++ m_pBackendDbusHelperDbus->setUsdMediaStateKeys(KEY_RFKILL_STATE, oldvalue); ++} ++ ++TEST_F(BackendDbusHelperTest, getUsdMediaKeys) ++{ ++ QString value = m_pBackendDbusHelperDbus->getUsdMediaKeys(KEY_WINDOW_SCREENSHOT).toString(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanSuspend) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanSuspend(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanReboot) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanReboot(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanPowerOff) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanPowerOff(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanSwitchUser) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanSwitchUser(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanHibernate) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanHibernate(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanLogout) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanLogout(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPowerManagerCanLockScreen) ++{ ++ bool value = m_pBackendDbusHelperDbus->getPowerManagerCanLockScreen(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, checkSystemUpgrade) ++{ ++ bool value = m_pBackendDbusHelperDbus->checkSystemUpgrade(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BackendDbusHelperTest, getPublicEncrypt) ++{ ++ QString value = m_pBackendDbusHelperDbus->getPublicEncrypt(); ++ ASSERT_EQ(value.isEmpty(), false); ++} +diff --git a/tests/unit_test_biometric_helper/CMakeLists.txt b/tests/unit_test_biometric_helper/CMakeLists.txt +new file mode 100644 +index 0000000..76fb9ed +--- /dev/null ++++ b/tests/unit_test_biometric_helper/CMakeLists.txt +@@ -0,0 +1,66 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++ ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/biometrichelper.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/dbusifs/giodbus.cpp ++ unit_test_biometric_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/biodefines.h ++ ../../src/dbusifs/biometrichelper.h ++ ../../src/dbusifs/giodbus.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${GLIB2_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_biometric_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_biometric_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_biometric_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++ ${GLIB2_LIBRARIES} ++) ++ +diff --git a/tests/unit_test_biometric_helper/main.cpp b/tests/unit_test_biometric_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_biometric_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp b/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp +new file mode 100644 +index 0000000..4889d3d +--- /dev/null ++++ b/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp +@@ -0,0 +1,131 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include <QtDBus> ++#include <QDBusAbstractInterface> ++ ++#include "../../src/dbusifs/biometrichelper.h" ++#include "../../src/dbusifs/giodbus.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class BiometricHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pABiometricHelperDbus = new BiometricHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pABiometricHelperDbus; ++ m_pABiometricHelperDbus = nullptr; ++ } ++ ++ static BiometricHelper *m_pABiometricHelperDbus; ++}; ++ ++BiometricHelper *BiometricHelperTest::m_pABiometricHelperDbus = nullptr; ++ ++TEST_F(BiometricHelperTest, Identify) ++{ ++ get_server_gvariant_stdout(-1); ++ QDBusPendingCall value = m_pABiometricHelperDbus->Identify(32, 1000, 0, -1); ++ ASSERT_EQ(value.isValid(), false); ++} ++ ++TEST_F(BiometricHelperTest, UkeyIdentify) ++{ ++ QDBusPendingCall value = m_pABiometricHelperDbus->UkeyIdentify(100, 2, 1000); ++ ASSERT_EQ(value.isValid(), false); ++} ++ ++TEST_F(BiometricHelperTest, GetHasUkeyFeature) ++{ ++ bool value = m_pABiometricHelperDbus->GetHasUkeyFeature(1000, 0, -1); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BiometricHelperTest, GetFeatureCount) ++{ ++ bool value = m_pABiometricHelperDbus->GetFeatureCount(1000, 0, -1); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(BiometricHelperTest, SetExtraInfo) ++{ ++ int value = m_pABiometricHelperDbus->SetExtraInfo("extra_info", "extra_info"); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BiometricHelperTest, StopOps) ++{ ++ int value = m_pABiometricHelperDbus->StopOps(32, 3000); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BiometricHelperTest, GetUserDevCount) ++{ ++ int value = m_pABiometricHelperDbus->GetUserDevCount(1000); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BiometricHelperTest, GetUserDevFeatureCount) ++{ ++ int value = m_pABiometricHelperDbus->GetUserDevFeatureCount(1000, 32); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BiometricHelperTest, GetDevList) ++{ ++ DeviceList value = m_pABiometricHelperDbus->GetDevList(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(BiometricHelperTest, GetUserFeatures) ++{ ++ FeatureMap value = m_pABiometricHelperDbus->GetUserFeatures(1000); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(BiometricHelperTest, GetDevCount) ++{ ++ int value = m_pABiometricHelperDbus->GetDevCount(); ++ ASSERT_EQ(value, 0); ++} ++ ++TEST_F(BiometricHelperTest, GetDevMesg) ++{ ++ QString value = m_pABiometricHelperDbus->GetDevMesg(32); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_EQ(cstr, ""); ++} ++ ++TEST_F(BiometricHelperTest, GetNotifyMesg) ++{ ++ QString value = m_pABiometricHelperDbus->GetNotifyMesg(32); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_EQ(cstr, ""); ++} ++ ++TEST_F(BiometricHelperTest, GetOpsMesg) ++{ ++ QString value = m_pABiometricHelperDbus->GetOpsMesg(32); ++ std::string str = value.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_EQ(cstr, ""); ++} ++ ++TEST_F(BiometricHelperTest, UpdateStatus) ++{ ++ StatusReslut status = m_pABiometricHelperDbus->UpdateStatus(32); ++ ASSERT_EQ(status.result , 0); ++ ASSERT_EQ(status.enable , 0); ++ ASSERT_EQ(status.devNum , 0); ++ ASSERT_EQ(status.devStatus , 0); ++ ASSERT_EQ(status.opsStatus , 0); ++ ASSERT_EQ(status.notifyMessageId , 0); ++} +diff --git a/tests/unit_test_common/CMakeLists.txt b/tests/unit_test_common/CMakeLists.txt +new file mode 100644 +index 0000000..ed9241f +--- /dev/null ++++ b/tests/unit_test_common/CMakeLists.txt +@@ -0,0 +1,89 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui Widgets X11Extras Svg DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++find_package(OpenSSL REQUIRED) ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++find_package(X11 REQUIRED) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/common/biodefines.cpp ++ ../../src/common/commonfunc.cpp ++ ../../src/common/configuration.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/common/rsac.cpp ++ ../../src/common/utils.cpp ++ ../../src/lock-dialog/languagesetting.cpp ++ unit_test_common.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/common/biodefines.h ++ ../../src/common/commonfunc.h ++ ../../src/common/configuration.h ++ ../../src/common/global_utils.h ++ ../../src/common/rsac.h ++ ../../src/common/utils.h ++ ../../src/lock-dialog/languagesetting.h ++ ) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${X11_INCLUDE_DIRS} ++) ++ ++qt5_add_resources(unit_test_common ++ assets.qrc ++ ) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_common ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_common ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::Widgets ++ Qt5::Svg ++ Qt5::X11Extras ++ ${QGS_LIBRARIES} ++ OpenSSL::Crypto ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_common ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++ ${GIOUNIX2_LIBRARIES} ++ ${X11_LIBRARIES} ++) +diff --git a/tests/unit_test_common/main.cpp b/tests/unit_test_common/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_common/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_common/unit_test_common.cpp b/tests/unit_test_common/unit_test_common.cpp +new file mode 100644 +index 0000000..e92efeb +--- /dev/null ++++ b/tests/unit_test_common/unit_test_common.cpp +@@ -0,0 +1,349 @@ ++#include "../../src/common/definetypes.h" ++#include "../../src/common/biodefines.h" ++#include "../../src/common/commonfunc.h" ++#include "../../src/common/configuration.h" ++#include "../../src/common/global_utils.h" ++#include "../../src/common/rsac.h" ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include <QIcon> ++#include <openssl/rsa.h> ++#include <openssl/pem.h> ++#include <openssl/err.h> ++#include <openssl/sha.h> ++#include <iostream> ++#include "../../src/common/rsac.h" ++#include "../../src/common/utils.h" ++#include "../../src/lock-dialog/languagesetting.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++// 辅助函数,用于初始化OpenSSL库 ++ ++void InitOpenSSL() { ++ ++ OpenSSL_add_all_algorithms(); ++ ++ ERR_load_crypto_strings(); ++ ++} ++ ++ ++ ++// 辅助函数,用于清理OpenSSL库 ++ ++void CleanupOpenSSL() { ++ ++ EVP_cleanup(); ++ ++ ERR_free_strings(); ++ ++} ++ ++class CommonTest : public testing::Test ++{ ++protected: ++ ++ void SetUp() override { ++ ++ InitOpenSSL(); ++ ++ } ++ ++ ++ ++ void TearDown() override { ++ ++ CleanupOpenSSL(); ++ ++ } ++ ++ RSAC rsac; ++}; ++ ++TEST_F(CommonTest, scaledPixmap) ++{ ++ setCursorCenter(); ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = scaledPixmap(pixmap); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, PixmapToRound) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = PixmapToRound(pixmap, 4); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, PixmapToRound2) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = PixmapToRound(pixmap, 0, 0, 0, 0); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, loadSvg) ++{ ++ QPixmap iconPixmap = loadSvg(":/image/assets/show-password.png", "white", 16); ++ ASSERT_EQ(iconPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, drawSymbolicColoredPixmap) ++{ ++ QPixmap retryIcon = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ ASSERT_EQ(drawSymbolicColoredPixmap(retryIcon, "white").isNull(), false); ++ ASSERT_EQ(getLoadingIcon(16).width(), 16); ++} ++ ++TEST_F(CommonTest, scaleBlurPixmap) ++{ ++ QPixmap *pixmap = new QPixmap(scaleBlurPixmap(16, 16, "/usr/share/background/house.png")); ++ ASSERT_EQ(pixmap->width(), 16); ++} ++ ++TEST_F(CommonTest, blurPixmap) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newpixmap = blurPixmap(pixmap); ++ ASSERT_EQ(newpixmap.width(), 16); ++} ++ ++TEST_F(CommonTest, getDeviceTypeTr) ++{ ++ ++ getDeviceTypeTr(BioT_FingerVein); ++ getDeviceTypeTr(BioT_Iris); ++ getDeviceTypeTr(BioT_Face); ++ getDeviceTypeTr(BioT_VoicePrint); ++ getDeviceTypeTr(UniT_General_Ukey); ++ getDeviceTypeTr(UniT_Remote); ++ getDeviceTypeTr(-1); ++ ASSERT_EQ(getDeviceTypeTr(BioT_FingerPrint).isEmpty(), false); ++} ++ ++TEST_F(CommonTest, getValue) ++{ ++ if (Configuration::instance()) { ++ QString color = Configuration::instance()->getValue("background-color").toString(); ++ ASSERT_EQ(color.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, getCurrentUser) ++{ ++ if (Configuration::instance()) { ++ Configuration::instance()->getCurrentUser(getenv("USER")); ++ } ++} ++ ++TEST_F(CommonTest, setValue) ++{ ++ if (Configuration::instance()) { ++ QString color = Configuration::instance()->getValue("backgroundPath").toString(); ++ QString oldvalue = Configuration::instance()->getUserConfig("backgroundPath").toString(); ++ Configuration::instance()->setValue("backgroundPath", oldvalue); ++ ASSERT_EQ(oldvalue.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, hasValue) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->hasValue("backgroundPath"); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++ ++TEST_F(CommonTest, getIs990) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->getIs990(); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++TEST_F(CommonTest, getLastNumLock) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->getLastNumLock(); ++ Configuration::instance()->saveLastNumLock(value); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++TEST_F(CommonTest, getRootBackgroundOption) ++{ ++ if (Configuration::instance()) { ++ int value = Configuration::instance()->getRootBackgroundOption(getenv("USER")); ++ ASSERT_EQ(value, 1); ++ } ++} ++ ++TEST_F(CommonTest, getDefaultBackgroundName) ++{ ++ if (Configuration::instance()) { ++ QString background = Configuration::instance()->getDefaultBackgroundName(); ++ ASSERT_EQ(background.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, onLanguageChanged) ++{ ++ if (LanguageSetting::instance()) { ++ LanguageSetting::instance()->onLanguageChanged("zh_HK.UTF-8"); ++ LanguageSetting::instance()->onLanguageChanged("zh_CN.UTF-8"); ++ } ++} ++ ++TEST_F(CommonTest, isCurUserSelf) ++{ ++ ASSERT_EQ(isCurUserSelf(getenv("USER")), true); ++ ASSERT_EQ(isCurUserSelf("lightdm"), false); ++ ASSERT_EQ(isCurUserSelf("test"), false); ++} ++ ++TEST_F(CommonTest, checkCapsLockState) ++{ ++ checkIslivecd(); ++ KillFocusOfKydroid(); ++ ASSERT_EQ(checkCapsLockState(), false); ++} ++ ++TEST_F(CommonTest, getDefaultFontSize) ++{ ++ ASSERT_EQ(getDefaultFontSize(), 14.0); ++} ++ ++TEST_F(CommonTest, getUserFontSize) ++{ ++ ASSERT_EQ(getUserFontSize(getenv("USER")), 14.0); ++} ++ ++TEST_F(CommonTest, getUserThemeColor) ++{ ++ ASSERT_EQ(getUserThemeColor(getenv("USER")), "test"); ++} ++ ++// 测试密钥生成并保存到文件 ++ ++TEST_F(CommonTest, GenerateKeyPairToFile) { ++ ++ QString priKeyFile = "test_private.pem"; ++ ++ QString pubKeyFile = "test_public.pem"; ++ ++ rsac.generateKeyPair(priKeyFile, pubKeyFile, 1024); ++ ++ ++ ++ // 这里可以添加额外的检查来验证文件是否成功生成且内容有效 ++ ++ // 例如,打开文件并读取内容,检查是否为有效的PEM格式密钥 ++ ++ // 但由于这是一个简单的测试示例,我们省略了这些步骤 ++} ++ ++ ++ ++// 测试密钥生成并保存到QByteArray ++ ++TEST_F(CommonTest, GenerateKeyPairToByteArray) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ // 检查生成的密钥是否非空 ++ ++ EXPECT_FALSE(privateKey.isEmpty()); ++ ++ EXPECT_FALSE(publicKey.isEmpty()); ++ ++ ++ ++ // 这里可以添加额外的检查来验证密钥的有效性 ++ ++ // 例如,使用OpenSSL函数解析生成的密钥并检查其属性 ++ ++ // 但由于这是一个简单的测试示例,我们省略了这些步骤 ++ ++} ++ ++ ++ ++// 测试加密和解密 ++ ++TEST_F(CommonTest, EncryptDecrypt) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ QByteArray plaintext = "Hello, RSA!"; ++ ++ QByteArray ciphertext; ++ ++ QByteArray decryptedtext; ++ ++ ++ ++ bool encryptResult = rsac.encrypt(plaintext, ciphertext, publicKey); ++ ++ EXPECT_TRUE(encryptResult); ++ ++ ++ ++ bool decryptResult = rsac.decrypt(ciphertext, decryptedtext, privateKey); ++ ++ EXPECT_TRUE(decryptResult); ++ ++ ++ ++ EXPECT_EQ(plaintext, decryptedtext); ++ ++} ++ ++ ++ ++// 测试签名和验签 ++ ++TEST_F(CommonTest, SignVerify) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ QByteArray message = "This is a test message."; ++ ++ QByteArray signature; ++ ++ bool signResult = rsac.sign(message, signature, privateKey); ++ ++ EXPECT_TRUE(signResult); ++ ++ bool verifyResult = rsac.verify(message, signature, publicKey); ++ ++ EXPECT_TRUE(verifyResult); ++ ++ // 尝试使用错误的消息进行验签,应该失败 ++ ++ bool verifyWithWrongMessageResult = rsac.verify("Wrong message.", signature, publicKey); ++ ++ EXPECT_FALSE(verifyWithWrongMessageResult); ++ ++} +diff --git a/tests/unit_test_dbus_interface/CMakeLists.txt b/tests/unit_test_dbus_interface/CMakeLists.txt +new file mode 100644 +index 0000000..ffc9e8c +--- /dev/null ++++ b/tests/unit_test_dbus_interface/CMakeLists.txt +@@ -0,0 +1,147 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus Network Test REQUIRED) ++find_package(OpenSSL REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) ++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量 ++find_library(PAM_LIBRARIES pam) ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/authpamthread.cpp ++ ../../src/lock-backend/pamauthenticate.cpp ++ ../../src/lock-backend/lightdmhelper.cpp ++ ../../src/lock-backend/dbusupperinterface.cpp ++ ../../src/lock-backend/gsettingshelper.cpp ++ ../../src/lock-backend/bioauthenticate.cpp ++ ../../src/lock-backend/switchuserutils.cpp ++ ../../src/dbusifs/accountshelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/common/configuration.cpp ++ ../../src/common/rsac.cpp ++ ../../src/dbusifs/giodbus.cpp ++ ../../src/dbusifs/uniauthservice.cpp ++ ../../src/lock-backend/securityuser.cpp ++ ../../src/dbusifs/freedesktophelper.cpp ++ ../../src/dbusifs/login1helper.cpp ++ ../../src/dbusifs/usdhelper.cpp ++ ../../src/dbusifs/upowerhelper.cpp ++ ../../src/dbusifs/sessionhelper.cpp ++ ../../src/dbusifs/dbusservermanager.cpp ++ ../../src/dbusifs/systemupgradehelper.cpp ++ ../../src/lock-backend/sessionwatcher.cpp ++ ../../src/dbusifs/kglobalaccelhelper.cpp ++ ../../src/dbusifs/libinputswitchevent.cpp ++ ../../src/lock-backend/personalizeddata.cpp ++ ../../src/dbusifs/biometrichelper.cpp ++ ../../src/dbusifs/device.cpp ++ ../../src/dbusifs/machinemodel.cpp ++ ../../src/dbusifs/enginedevice.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/QtSingleApplication/qtlocalpeer.cpp ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp ++ unit_test_dbus_interface.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/authpamthread.h ++ ../../src/lock-backend/pamauthenticate.h ++ ../../src/lock-backend/lightdmhelper.h ++ ../../src/lock-backend/dbusupperinterface.h ++ ../../src/lock-backend/gsettingshelper.h ++ ../../src/lock-backend/bioauthenticate.h ++ ../../src/lock-backend/switchuserutils.h ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/common/configuration.h ++ ../../src/common/rsac.h ++ ../../src/dbusifs/giodbus.h ++ ../../src/dbusifs/accountshelper.h ++ ../../src/common/configuration.h ++ ../../src/dbusifs/uniauthservice.h ++ ../../src/lock-backend/securityuser.h ++ ../../src/dbusifs/freedesktophelper.h ++ ../../src/dbusifs/login1helper.h ++ ../../src/dbusifs/usdhelper.h ++ ../../src/dbusifs/upowerhelper.h ++ ../../src/dbusifs/dbusservermanager.h ++ ../../src/dbusifs/sessionhelper.h ++ ../../src/dbusifs/systemupgradehelper.h ++ ../../src/lock-backend/sessionwatcher.h ++ ../../src/dbusifs/kglobalaccelhelper.h ++ ../../src/dbusifs/libinputswitchevent.h ++ ../../src/lock-backend/personalizeddata.h ++ ../../src/dbusifs/biometrichelper.h ++ ../../src/dbusifs/device.h ++ ../../src/dbusifs/enginedevice.h ++ ../../src/dbusifs/machinemodel.h ++ ../../src/common/biodefines.h ++ ../kt-test-utils/cpp-stub-ext/stubext.h ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.h ++ ../../src/QtSingleApplication/qtlocalpeer.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${Qt5Test_INCLUDE_DIRS} ++ ${LIGHTDM-QT5-3_INCLUDE_DIRS} ++ ${LIBSYSTEMD_INCLUDE_DIRS} ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/ ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_dbus_interface ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_dbus_interface ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::Test ++ Qt5::Network ++ ${QGS_LIBRARIES} ++ ${PAM_LIBRARIES} ++ ${LIGHTDM-QT5-3_LIBRARIES} ++ ${LIBSYSTEMD_LIBRARIES} ++ OpenSSL::Crypto ++ -lukuiinputgatherclient ++ ${GIOUNIX2_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_dbus_interface ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_dbus_interface/main.cpp b/tests/unit_test_dbus_interface/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_dbus_interface/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp b/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp +new file mode 100644 +index 0000000..3f4e5ec +--- /dev/null ++++ b/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp +@@ -0,0 +1,524 @@ ++#include <gtest/gtest.h> ++#include <memory> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <string.h> ++#include <security/pam_appl.h> ++#include <gtest/gtest.h> ++#include <QCoreApplication> ++#include <QLightDM/Greeter> ++#include <QSocketNotifier> ++#include <QDebug> ++#include <QSignalSpy> ++#include <QJsonValue> ++#include <QJsonObject> ++#include <QJsonDocument> ++#include <QJsonArray> ++#include "../../src/lock-backend/authpamthread.h" ++#include "../../src/lock-backend/pamauthenticate.h" ++#include "../../src/lock-backend/lightdmhelper.h" ++#include "../../src/lock-backend/dbusupperinterface.h" ++#include "../../src/dbusifs/accountshelper.h" ++ ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class DbusUpperInterfaceTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ ++ StubExt st; ++ st.set_lamda(&LightDMHelper::connectToDaemonSync, []() { return true; }); ++ st.set_lamda(&isGreeterMode, []() { return true; }); ++ m_pAccountsHelperDbus = QSharedPointer<AccountsHelper>(new AccountsHelper()); ++ m_pLightDMHelperDbus = new LightDMHelper(m_pAccountsHelperDbus, Configuration::instance()); ++ m_pDbusUpperInterfaceDbus = new DbusUpperInterface(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pDbusUpperInterfaceDbus; ++ m_pDbusUpperInterfaceDbus = nullptr; ++ ++ delete m_pLightDMHelperDbus; ++ m_pLightDMHelperDbus = nullptr; ++ ++ m_pAccountsHelperDbus.reset(); ++ } ++ ++ static DbusUpperInterface *m_pDbusUpperInterfaceDbus; ++ ++ static LightDMHelper *m_pLightDMHelperDbus; ++ ++ static QSharedPointer<AccountsHelper> m_pAccountsHelperDbus; ++}; ++ ++DbusUpperInterface *DbusUpperInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr; ++LightDMHelper *DbusUpperInterfaceTest::m_pLightDMHelperDbus = nullptr; ++QSharedPointer<AccountsHelper> DbusUpperInterfaceTest::m_pAccountsHelperDbus = nullptr; ++ ++TEST_F(DbusUpperInterfaceTest, GetSlpState) ++{ ++ m_pDbusUpperInterfaceDbus->onNameLost("test"); ++ bool value = m_pDbusUpperInterfaceDbus->GetSlpState(); ++ ++ m_pLightDMHelperDbus->getLoginUserCount(); ++ m_pLightDMHelperDbus->findUserByUid(getuid()); ++ ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetBlankState) ++{ ++ bool value = m_pDbusUpperInterfaceDbus->GetBlankState(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetLockState) ++{ ++ bool value = m_pDbusUpperInterfaceDbus->GetLockState(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, CheckAppVersion) ++{ ++ bool value = m_pDbusUpperInterfaceDbus->CheckAppVersion(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, checkScreenDialogRunning) ++{ ++ m_pDbusUpperInterfaceDbus->LockStartupMode(); ++ m_pDbusUpperInterfaceDbus->SessionTools(); ++ m_pDbusUpperInterfaceDbus->Lock(); ++ m_pDbusUpperInterfaceDbus->SwitchUser(); ++ m_pDbusUpperInterfaceDbus->AppBlockWindow("Suspend"); ++ m_pDbusUpperInterfaceDbus->MultiUserBlockWindow("Restart"); ++ m_pDbusUpperInterfaceDbus->onShowBlankScreensaver(); ++ m_pDbusUpperInterfaceDbus->ShowScreensaver(); ++ m_pDbusUpperInterfaceDbus->LockScreensaver(); ++ // m_pDbusUpperInterfaceDbus->Suspend(); ++ bool value = m_pDbusUpperInterfaceDbus->checkScreenDialogRunning(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GenerateBatteryArgsList) ++{ ++ QJsonArray value = m_pDbusUpperInterfaceDbus->GenerateBatteryArgsList(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getSleepLockCheck) ++{ ++ QJsonArray value = m_pDbusUpperInterfaceDbus->getSleepLockCheck(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getShutdownLockcheck) ++{ ++ QJsonArray value = m_pDbusUpperInterfaceDbus->getShutdownLockcheck(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getSaverTheme) ++{ ++ QJsonArray value = m_pDbusUpperInterfaceDbus->getSaverTheme(); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getBatteryIconName) ++{ ++ QString value = m_pDbusUpperInterfaceDbus->getBatteryIconName(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getIsBattery) ++{ ++ bool value = m_pDbusUpperInterfaceDbus->getIsBattery(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetDefaultAuthUser) ++{ ++ StubExt st; ++ st.set_lamda(&isGreeterMode, []() { return true; }); ++ QString value = m_pDbusUpperInterfaceDbus->GetDefaultAuthUser(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetCurrentSession) ++{ ++ QString value = m_pDbusUpperInterfaceDbus->GetCurrentSession(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GenerateSessionInfoList) ++{ ++ QJsonArray value = m_pDbusUpperInterfaceDbus->GenerateSessionInfoList(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetCurrentUser) ++{ ++ QString value = m_pDbusUpperInterfaceDbus->GetCurrentUser(); ++ ASSERT_EQ(value.isEmpty(), false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, getCurTabletMode) ++{ ++ bool value = m_pDbusUpperInterfaceDbus->getCurTabletMode(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GenerateUserInfoList) ++{ ++ // m_pDbusUpperInterfaceDbus->GenerateUserInfoList(); ++ // qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ; ++ // m_pDbusUpperInterfaceDbus->onUsersInfoChanged(); ++ m_pDbusUpperInterfaceDbus->onLogin1ReqLock(); ++ m_pDbusUpperInterfaceDbus->onLogin1ReqUnLock(); ++ m_pDbusUpperInterfaceDbus->onLogin1PrepareForSleep(true); ++ m_pDbusUpperInterfaceDbus->onLogin1PrepareForSleep(false); ++ m_pDbusUpperInterfaceDbus->onLogin1SessionActiveChanged(true); ++ m_pDbusUpperInterfaceDbus->onBlockInhibitedChanged("ShutDown"); ++ m_pDbusUpperInterfaceDbus->delayLockScreen(); ++ m_pDbusUpperInterfaceDbus->stopDelayLockScreen(); ++ m_pDbusUpperInterfaceDbus->onBatteryStatusChanged("test"); ++ m_pDbusUpperInterfaceDbus->onSessionIdleReceived(); ++ m_pDbusUpperInterfaceDbus->onSessionIdleExit(); ++ m_pDbusUpperInterfaceDbus->onLockScreenTimeout(); ++ m_pDbusUpperInterfaceDbus->onBatteryChanged(QStringList()); ++ m_pDbusUpperInterfaceDbus->onLidStateChanged(false); ++} ++ ++TEST_F(DbusUpperInterfaceTest, SendUpdateInfoSig) ++{ ++ QJsonObject getjsonCmd; ++ QJsonParseError jsonParseError; ++ QJsonObject objRes; ++ QVariant varValue; ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF; ++ getjsonCmd["Key"] = KEY_IDLE_DELAY; ++ const QJsonDocument jsonDoc = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc.object(); ++ varValue = objRes.value(KEY_IDLE_DELAY); ++ m_pDbusUpperInterfaceDbus->onLockScreenConfigChanged(KEY_IDLE_DELAY, varValue.toDouble()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF; ++ getjsonCmd["Key"] = KEY_SHOW_REST_TIME; ++ const QJsonDocument jsonDoc1 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc1.object(); ++ varValue = objRes.value(KEY_SHOW_REST_TIME); ++ m_pDbusUpperInterfaceDbus->onScreenSaverConfigChanged(KEY_SHOW_REST_TIME, varValue.toDouble()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF; ++ getjsonCmd["Key"] = KEY_SLEEP_COMPUTER_AC; ++ const QJsonDocument jsonDoc2 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc2.object(); ++ varValue = objRes.value(KEY_SLEEP_COMPUTER_AC); ++ m_pDbusUpperInterfaceDbus->onPowerManagerConfigChanged(KEY_SLEEP_COMPUTER_AC, varValue.toDouble()); ++ ++ // getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_MATEBG_CONF; ++ // getjsonCmd["Key"] = KEY_PICTURE_FILENAME; ++ // const QJsonDocument jsonDoc3 = ++ // QJsonDocument::fromJson(m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ // &jsonParseError); objRes = jsonDoc3.object(); varValue = objRes.value(KEY_PICTURE_FILENAME); ++ // m_pDbusUpperInterfaceDbus->onMateBgConfigChanged(KEY_PICTURE_FILENAME, varValue.toString()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF; ++ getjsonCmd["Key"] = KEY_HOUR_SYSTEM; ++ const QJsonDocument jsonDoc4 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc4.object(); ++ varValue = objRes.value(KEY_HOUR_SYSTEM); ++ m_pDbusUpperInterfaceDbus->onUkccPluginsConfigChanged(KEY_HOUR_SYSTEM, varValue.toDouble()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF; ++ getjsonCmd["Key"] = KEY_SYSTEM_FONT_SIZE; ++ const QJsonDocument jsonDoc5 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc5.object(); ++ varValue = objRes.value(KEY_SYSTEM_FONT_SIZE); ++ m_pDbusUpperInterfaceDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT_SIZE, varValue.toDouble()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF; ++ getjsonCmd["Key"] = KEY_SESSION_IDLE; ++ const QJsonDocument jsonDoc6 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc6.object(); ++ varValue = objRes.value(KEY_SESSION_IDLE); ++ m_pDbusUpperInterfaceDbus->onSessionConfigChanged(KEY_SESSION_IDLE, varValue.toDouble()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_KEYBOARD_CONF; ++ getjsonCmd["Key"] = KEY_CAPSLOCK_STATUS; ++ const QJsonDocument jsonDoc7 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc7.object(); ++ varValue = objRes.value(KEY_CAPSLOCK_STATUS); ++ m_pDbusUpperInterfaceDbus->onKeyboardConfigChanged(KEY_CAPSLOCK_STATUS, varValue.toBool()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIAKEYS_CONF; ++ getjsonCmd["Key"] = KEY_AREA_SCREENSHOT; ++ const QJsonDocument jsonDoc8 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc8.object(); ++ varValue = objRes.value(KEY_AREA_SCREENSHOT); ++ m_pDbusUpperInterfaceDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT, varValue.toString()); ++ ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF; ++ getjsonCmd["Key"] = KEY_RFKILL_STATE; ++ const QJsonDocument jsonDoc9 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ objRes = jsonDoc9.object(); ++ varValue = objRes.value(KEY_RFKILL_STATE); ++ m_pDbusUpperInterfaceDbus->onUsdMediaStateKeysConfigChanged(KEY_RFKILL_STATE, varValue.toDouble()); ++} ++ ++TEST_F(DbusUpperInterfaceTest, GetInformation) ++{ ++ // QList<QVariant> argumentList; ++ // argumentList << QVariant::fromValue(QString(QJsonDocument(jsonCmd).toJson())); ++ QList<int> list{ /*LOCK_CMD_ID_GET_USERINFO_LIST, */ LOCK_CMD_ID_GET_DEFAULT_AUTH_USER, ++ LOCK_CMD_ID_GET_CURRENT_USER, ++ LOCK_CMD_ID_GET_SESSIONS_LIST, ++ LOCK_CMD_ID_GET_CURRENT_SESSION, ++ LOCK_CMD_ID_LOGIN1_IS_SESSION_ACTIVE, ++ LOCK_CMD_ID_GET_AGREEMENT, ++ LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF, ++ /*LOCK_CMD_ID_GSETTINGS_GET_MATEBG_CONF,*/ LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_KEYBOARD_CONF, ++ LOCK_CMD_ID_PAMAUTH_IS_AUTHENTICATED, ++ LOCK_CMD_ID_PAMAUTH_IS_INAUTHTICATION, ++ LOCK_CMD_ID_PAMAUTH_GET_AUTHUSER, ++ LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIAKEYS_CONF, ++ LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANHIBERNATE, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANPOWEROFF, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANREBOOT, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANSUSPEND, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANLOGOUT, ++ LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANLOCKSCREEN, ++ LOCK_CMD_ID_SYSTEM_UPGRADE_CHECK, ++ LOCK_CMD_ID_UPOWER_BATTERY_STATUS, ++ LOCK_CMD_ID_UPOWER_IS_BATTERY, ++ LOCK_CMD_ID_UPOWER_BATTERY, ++ LOCK_CMD_ID_SESSION_GET_SLEEP_LOCKCHECK, ++ LOCK_CMD_ID_SESSION_GET_SHUTDOWN_LOCKCHECK, ++ LOCK_CMD_ID_LOCK_SCREEN_GET_THEMES, ++ LOCK_CMD_ID_BIOAUTH_GET_AVAILABLE_DEVICES, ++ LOCK_CMD_ID_BIOAUTH_GET_DISABLED_DEVICES, ++ LOCK_CMD_ID_BIOAUTH_GET_STATE, ++ LOCK_CMD_ID_BIOAUTH_GET_CURDEVICE, ++ LOCK_CMD_ID_BIOAUTH_FIND_DEVICE_BY_ID, ++ LOCK_CMD_ID_BIOAUTH_FIND_DEVICE_BY_NAME, ++ LOCK_CMD_ID_BIOAUTH_GET_DEFAULT_DEVICE, ++ LOCK_CMD_ID_GET_PUBLIC_KEY, ++ LOCK_CMD_ID_TABLET_MODE, ++ -1 }; ++ ++ for (int i = 0; i < list.count(); i++) { ++ QJsonObject jsonCmd; ++ jsonCmd["CmdId"] = list.at(i); ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(jsonCmd).toJson())); ++ } ++} ++ ++TEST_F(DbusUpperInterfaceTest, SetInformation) ++{ ++ QJsonObject jsonCmd; ++ jsonCmd["CmdId"] = LOCK_CMD_ID_SET_USER; ++ jsonCmd["Content"] = getenv("USER"); ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd1; ++ jsonCmd1["CmdId"] = LOCK_CMD_ID_SWITCH_TO_USER; ++ jsonCmd1["Content"] = getenv("USER"); ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd1).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd2; ++ jsonCmd2["CmdId"] = LOCK_CMD_ID_SET_SESSION; ++ jsonCmd2["Content"] = "testSession"; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd2).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd3; ++ jsonCmd3["CmdId"] = LOCK_CMD_ID_START_SESSION; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd3).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd; ++ getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF; ++ getjsonCmd["Key"] = KEY_IDLE_DELAY; ++ QJsonParseError jsonParseError; ++ const QJsonDocument jsonDoc = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(), ++ &jsonParseError); ++ QJsonObject objRes = jsonDoc.object(); ++ QVariant varValue = objRes.value(KEY_IDLE_DELAY); ++ QJsonObject jsonCmd4; ++ jsonCmd4["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_LOCKSCREEN_CONF; ++ jsonCmd4["Content"] = varValue.toDouble(); ++ jsonCmd4["Key"] = KEY_IDLE_DELAY; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd4).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd5; ++ getjsonCmd5["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF; ++ getjsonCmd5["Key"] = KEY_VIDEO_SIZE; ++ QJsonParseError jsonParseError5; ++ const QJsonDocument jsonDoc5 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd5).toJson())).toUtf8(), ++ &jsonParseError5); ++ QJsonObject objRes5 = jsonDoc5.object(); ++ QVariant varValue5 = objRes5.value(KEY_VIDEO_SIZE); ++ QJsonObject jsonCmd5; ++ jsonCmd5["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_SCREENSAVER_CONF; ++ jsonCmd5["Content"] = varValue5.toDouble(); ++ jsonCmd5["Key"] = KEY_VIDEO_SIZE; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd5).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd6; ++ getjsonCmd6["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF; ++ getjsonCmd6["Key"] = KEY_SLEEP_COMPUTER_AC; ++ QJsonParseError jsonParseError6; ++ const QJsonDocument jsonDoc6 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd6).toJson())).toUtf8(), ++ &jsonParseError6); ++ QJsonObject objRes6 = jsonDoc6.object(); ++ QVariant varValue6 = objRes6.value(KEY_SLEEP_COMPUTER_AC); ++ QJsonObject jsonCmd6; ++ jsonCmd6["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_POWERMANAGER_CONF; ++ jsonCmd6["Content"] = varValue6.toDouble(); ++ jsonCmd6["Key"] = KEY_SLEEP_COMPUTER_AC; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd6).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd7; ++ getjsonCmd7["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF; ++ getjsonCmd7["Key"] = KEY_HOUR_SYSTEM; ++ QJsonParseError jsonParseError7; ++ const QJsonDocument jsonDoc7 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd7).toJson())).toUtf8(), ++ &jsonParseError7); ++ QJsonObject objRes7 = jsonDoc7.object(); ++ QVariant varValue7 = objRes7.value(KEY_HOUR_SYSTEM); ++ QJsonObject jsonCmd7; ++ jsonCmd7["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_UKCCPLUGINS_CONF; ++ jsonCmd7["Content"] = varValue7.toDouble(); ++ jsonCmd7["Key"] = KEY_HOUR_SYSTEM; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd7).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd8; ++ getjsonCmd8["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF; ++ getjsonCmd8["Key"] = KEY_SYSTEM_FONT_SIZE; ++ QJsonParseError jsonParseError8; ++ const QJsonDocument jsonDoc8 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd8).toJson())).toUtf8(), ++ &jsonParseError8); ++ QJsonObject objRes8 = jsonDoc8.object(); ++ QVariant varValue8 = objRes8.value(KEY_SYSTEM_FONT_SIZE); ++ QJsonObject jsonCmd8; ++ jsonCmd8["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_THEMESTYLE_CONF; ++ jsonCmd8["Content"] = varValue8.toDouble(); ++ jsonCmd8["Key"] = KEY_SYSTEM_FONT_SIZE; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd8).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd9; ++ getjsonCmd9["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF; ++ getjsonCmd9["Key"] = KEY_SESSION_IDLE; ++ QJsonParseError jsonParseError9; ++ const QJsonDocument jsonDoc9 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd9).toJson())).toUtf8(), ++ &jsonParseError9); ++ QJsonObject objRes9 = jsonDoc9.object(); ++ QVariant varValue9 = objRes9.value(KEY_SESSION_IDLE); ++ QJsonObject jsonCmd9; ++ jsonCmd9["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_SESSION_CONF; ++ jsonCmd9["Content"] = varValue9.toDouble(); ++ jsonCmd9["Key"] = KEY_SESSION_IDLE; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd9).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd10; ++ jsonCmd10["CmdId"] = LOCK_CMD_ID_PAMAUTH_AUTHENTICATE; ++ jsonCmd10["Content"] = getenv("USER"); ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd10).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd11; ++ jsonCmd11["CmdId"] = LOCK_CMD_ID_PAMAUTH_RESPOND; ++ jsonCmd11["Content"] = "test"; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd11).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd12; ++ jsonCmd12["CmdId"] = LOCK_CMD_ID_PAMAUTH_AUTHENTICATE_CANCEL; ++ // jsonCmd12["Content"] = "test"; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd12).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd13; ++ jsonCmd13["CmdId"] = LOCK_CMD_ID_USD_MEDIAKEYS; ++ jsonCmd13["Content"] = VOLUME_DOWN_KEY; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd13).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd14; ++ jsonCmd14["CmdId"] = LOCK_CMD_ID_LOGIN1_SET_POWER_MANAGER; ++ jsonCmd14["Content"] = "LockScreen"; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd14).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd15; ++ jsonCmd15["CmdId"] = LOCK_CMD_ID_LOCK_STATE_CHANGED; ++ jsonCmd15["Content"] = false; ++ jsonCmd15["SessionTools"] = false; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd15).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd16; ++ jsonCmd16["CmdId"] = LOCK_CMD_ID_BIOAUTH_STARTAUTH; ++ jsonCmd16["UserId"] = 1000; ++ jsonCmd16["DevId"] = 101; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd16).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd17; ++ jsonCmd17["CmdId"] = LOCK_CMD_ID_BIOAUTH_STOPAUTH; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd17).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd18; ++ jsonCmd18["CmdId"] = LOCK_CMD_ID_KWIN_BLOCK_SHORTCUT; ++ jsonCmd18["Content"] = true; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd18).toJson()).toUtf8()); ++ ++ QJsonObject jsonCmd19; ++ jsonCmd19["CmdId"] = LOCK_CMD_ID_KWIN_BLOCK_SHORTCUT; ++ jsonCmd19["Content"] = false; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd19).toJson()).toUtf8()); ++ ++ QJsonObject getjsonCmd20; ++ getjsonCmd20["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF; ++ getjsonCmd20["Key"] = KEY_RFKILL_STATE; ++ QJsonParseError jsonParseError20; ++ const QJsonDocument jsonDoc20 = QJsonDocument::fromJson( ++ m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd20).toJson())).toUtf8(), ++ &jsonParseError20); ++ QJsonObject objRes20 = jsonDoc20.object(); ++ QVariant varValue20 = objRes20.value(KEY_RFKILL_STATE); ++ QJsonObject jsonCmd20; ++ jsonCmd20["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_USD_MEDIA_STATE_KEYS_CONF; ++ jsonCmd20["Content"] = varValue20.toDouble(); ++ jsonCmd20["Key"] = KEY_RFKILL_STATE; ++ m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd20).toJson()).toUtf8()); ++} +diff --git a/tests/unit_test_display_service/CMakeLists.txt b/tests/unit_test_display_service/CMakeLists.txt +new file mode 100644 +index 0000000..ef6b96f +--- /dev/null ++++ b/tests/unit_test_display_service/CMakeLists.txt +@@ -0,0 +1,59 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/common/displayservice.cpp ++ unit_test_display_service.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/displayservice.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_display_service ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_display_service ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_display_service ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_display_service/main.cpp b/tests/unit_test_display_service/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_display_service/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_display_service/unit_test_display_service.cpp b/tests/unit_test_display_service/unit_test_display_service.cpp +new file mode 100644 +index 0000000..493f0f3 +--- /dev/null ++++ b/tests/unit_test_display_service/unit_test_display_service.cpp +@@ -0,0 +1,69 @@ ++#include <gtest/gtest.h> ++ ++#include "../../src/common/displayservice.h" ++ ++class DisplayServiceTest : public testing::Test ++{ ++protected: ++// static void SetUpTestSuite() ++// { ++// m_pGSettingsHelperDbus = new GSettingsHelper(); ++// } ++ ++// static void TearDownTestSuite() ++// { ++// delete m_pGSettingsHelperDbus; ++// m_pGSettingsHelperDbus = nullptr; ++// } ++ ++// static GSettingsHelper *m_pGSettingsHelperDbus; ++}; ++ ++//GSettingsHelper *DisplayServiceTest::m_pGSettingsHelperDbus = nullptr; ++ ++// 测试 switchDisplayMode 函数 ++TEST_F(DisplayServiceTest, SwitchDisplayMode) { ++ // 测试 DISPLAY_MODE_ORI ++ bool value = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_ORI); ++ EXPECT_EQ(value, false); ++ ++ // 测试 DISPLAY_MODE_CLONE ++ bool value1 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_CLONE); ++ EXPECT_EQ(value1, false); ++ ++ // 测试 DISPLAY_MODE_EXTEND ++ bool value2 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_EXTEND); ++ EXPECT_EQ(value2, false); ++ ++ // 测试 DISPLAY_MODE_ONLY_OUT ++ bool value3 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_ONLY_OUT); ++ EXPECT_EQ(value3, false); ++} ++ ++ ++// 测试 setOneDisplayMode 函数 ++TEST_F(DisplayServiceTest, SetOneDisplayMode) { ++ // 测试使用 xrandr ++ DisplayService::instance()->setOneDisplayMode(); ++} ++ ++ ++// 测试 setCurUserName 函数 ++TEST_F(DisplayServiceTest, SetCurUserName) { ++ DisplayService::instance()->setCurUserName(getenv("USER")); ++} ++ ++ ++// 测试 isSaveParamInUsed 函数 ++TEST_F(DisplayServiceTest, IsSaveParamInUsed) { ++ EXPECT_TRUE(DisplayService::instance()->isSaveParamInUsed()); ++ ++ EXPECT_FALSE(DisplayService::instance()->isSaveParamInUsed()); ++} ++ ++ ++// 测试 isJJW7200 函数 ++TEST_F(DisplayServiceTest, IsJJW7200) { ++ int value = DisplayService::instance()->isJJW7200(); ++ EXPECT_EQ(value, 0); ++} +diff --git a/tests/unit_test_engine_device/CMakeLists.txt b/tests/unit_test_engine_device/CMakeLists.txt +new file mode 100644 +index 0000000..c7b4631 +--- /dev/null ++++ b/tests/unit_test_engine_device/CMakeLists.txt +@@ -0,0 +1,66 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus Test REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/enginedevice.cpp ++ ../../src/dbusifs/device.cpp ++ ../../src/dbusifs/upowerhelper.cpp ++ unit_test_engine_device.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/dbusifs/enginedevice.h ++ ../../src/dbusifs/upowerhelper.h ++ ../../src/dbusifs/device.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${Qt5Test_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_engine_device ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_engine_device ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::Test ++ ${QGS_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_engine_device ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_engine_device/main.cpp b/tests/unit_test_engine_device/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_engine_device/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_engine_device/unit_test_engine_device.cpp b/tests/unit_test_engine_device/unit_test_engine_device.cpp +new file mode 100644 +index 0000000..e48810c +--- /dev/null ++++ b/tests/unit_test_engine_device/unit_test_engine_device.cpp +@@ -0,0 +1,451 @@ ++#include "../../src/dbusifs/enginedevice.h" ++#include "../../src/dbusifs/device.h" ++#include "../../src/dbusifs/upowerhelper.h" ++#include <gtest/gtest.h> ++#include <QDBusMessage> ++#include <QDBusConnection> ++#include <QDBusInterface> ++#include <QDBusConnectionInterface> ++#include <QVariant> ++#include <QList> ++#include <QObject> ++#include <QStringList> ++#include <QGSettings> ++#include <QDebug> ++#include <QCoreApplication> ++#include <QSignalSpy> ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class EngineDeviceTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pEngineDeviceDbus = new EngineDevice(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pEngineDeviceDbus; ++ m_pEngineDeviceDbus = nullptr; ++ } ++ ++ static EngineDevice *m_pEngineDeviceDbus; ++}; ++ ++EngineDevice *EngineDeviceTest::m_pEngineDeviceDbus = nullptr; ++ ++ ++// 测试 power_device_get_devices 函数 ++TEST_F(EngineDeviceTest, power_device_get_devices) { ++ // 首先,确保 QDBus 服务正常运行,这里假设 QDBus 服务可以正常返回一些测试数据 ++ m_pEngineDeviceDbus->power_device_get_devices(); ++ ++ ++ // 检查 devices 列表是否不为空 ++ EXPECT_GT(m_pEngineDeviceDbus->devices.size(), 0); ++ ++ ++ // 可以进一步检查 devices 列表中元素的属性,例如: ++ if (!m_pEngineDeviceDbus->devices.isEmpty()) { ++ DEVICE *device = m_pEngineDeviceDbus->devices.first(); ++ EXPECT_FALSE(device->m_dev.path.isEmpty()); ++ } ++} ++ ++ ++// 测试 getProperty 函数 ++TEST_F(EngineDeviceTest, getProperty) { ++ DEV dev; ++ QString testPath = "/test/path"; ++ ++ ++ // 这里假设 QDBus 服务会正常响应 ++ m_pEngineDeviceDbus->getProperty(testPath, dev); ++ ++ ++ // 检查返回的属性是否符合预期 ++ EXPECT_EQ(dev.kind, UP_DEVICE_KIND_UNKNOWN); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.Type, ""); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.Model, ""); // 根据实际情况修改期望的结果 ++ EXPECT_FALSE(dev.IsPresent); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.PowerSupply, ""); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.Percentage, 0.0); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.Online, ""); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.State, UP_DEVICE_STATE_UNKNOWN); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.TimeToEmpty, 0); // 根据实际情况修改期望的结果 ++ EXPECT_EQ(dev.TimeToFull, 0); // 根据实际情况修改期望的结果 ++} ++ ++ ++// 测试 boolToString 函数 ++TEST_F(EngineDeviceTest, boolToString) { ++ EXPECT_EQ(m_pEngineDeviceDbus->boolToString(true), "yes"); ++ EXPECT_EQ(m_pEngineDeviceDbus->boolToString(false), "no"); ++} ++ ++ ++// 测试 putAttributes 函数 ++TEST_F(EngineDeviceTest, putAttributes) { ++ QMap<QString, QVariant> map; ++ map["TimeToFull"] = QVariant(200); ++ map["TimeToEmpty"] = QVariant(100); ++ map["State"] = QVariant(2); ++ map["Percentage"] = QVariant(50.0); ++ map["PowerSupply"] = QVariant(true); ++ map["IsPresent"] = QVariant(true); ++ ++ ++ DEV btrDetailData; ++ m_pEngineDeviceDbus->putAttributes(map, btrDetailData); ++ ++ ++ EXPECT_EQ(btrDetailData.TimeToFull, 200); ++ EXPECT_EQ(btrDetailData.TimeToEmpty, 100); ++ EXPECT_EQ(btrDetailData.State, 2); ++ EXPECT_EQ(btrDetailData.Percentage, 5.0); ++ EXPECT_EQ(btrDetailData.PowerSupply, "Yes"); ++ EXPECT_EQ(btrDetailData.IsPresent, true); ++} ++ ++ ++// 测试 power_device_change_callback 函数 ++TEST_F(EngineDeviceTest, power_device_change_callback) { ++// DEVICE *device = new DEVICE; ++// device->m_dev.path = "/test/path"; ++// engineDevice->devices.append(device); ++// QDBusMessage msg = QDBusMessage::createMethodCall(DBUS_SERVICE, "/test/path", DBUS_INTERFACE_PRO, "PropertiesChanged"); ++// msg.setArguments({ QVariant("interface"), QVariant::fromValue(QDBusArgument::fromVariantMap({ ++// { "TimeToFull", QVariant(300) } ++// })) }); ++// engineDevice->power_device_change_callback(msg, "/test/path"); ++// EXPECT_EQ(device->m_dev.TimeToFull, 300); ++// delete device; ++} ++ ++ ++// 测试 power_device_recalculate_state 函数 ++TEST_F(EngineDeviceTest, power_device_recalculate_state) { ++ // 准备一些测试数据 ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ m_pEngineDeviceDbus->devices.append(device); ++ ++ ++ // 使用 QSignalSpy 监听信号 ++// QSignalSpy summarySpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_summary_change(QString))); ++// QSignalSpy stateSpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_Battery_State(QStringList))); ++ ++ ++ m_pEngineDeviceDbus->power_device_recalculate_state(); ++ ++ ++ // 检查信号是否触发 ++// EXPECT_EQ(summarySpy.count(), 1); ++// EXPECT_EQ(stateSpy.count(), 1); ++ ++ ++ delete device; ++} ++ ++ ++// 测试 engine_recalculate_summary 函数 ++TEST_F(EngineDeviceTest, engine_recalculate_summary) { ++ // 准备一些测试数据 ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ m_pEngineDeviceDbus->devices.append(device); ++ ++ ++ // 使用 QSignalSpy 监听信号 ++// QSignalSpy summarySpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_summary_change(QString))); ++// QSignalSpy stateSpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_Battery_State(QStringList))); ++ ++ ++ bool result = m_pEngineDeviceDbus->engine_recalculate_summary(); ++ ++ ++ // 检查函数返回值和信号触发情况 ++ EXPECT_TRUE(result); ++// EXPECT_EQ(summarySpy.count(), 1); ++// EXPECT_EQ(stateSpy.count(), 1); ++ ++ ++ delete device; ++} ++ ++ ++// 测试 engine_get_state 函数 ++TEST_F(EngineDeviceTest, engine_get_state) { ++ // 准备一些测试数据 ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ m_pEngineDeviceDbus->devices.append(device); ++ QStringList stateList = m_pEngineDeviceDbus->engine_get_state(); ++ // 检查返回的状态列表是否符合预期 ++ EXPECT_FALSE(stateList.isEmpty()); ++ delete device; ++} ++ ++ ++// 测试 engine_get_Battery_State 函数 ++TEST_F(EngineDeviceTest, engine_get_Battery_State) { ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ device->m_dev.Percentage = 50.0; ++ device->m_dev.TimeToEmpty = 100; ++ QStringList stateList = m_pEngineDeviceDbus->engine_get_Battery_State(device); ++ // 检查返回的状态列表元素是否符合预期 ++ EXPECT_EQ(stateList.size(), 3); ++ EXPECT_EQ(stateList[0], "50"); ++ EXPECT_EQ(stateList[1], QString::number(UP_DEVICE_STATE_CHARGING)); ++ EXPECT_EQ(stateList[2], "100"); ++ ++ ++ delete device; ++} ++ ++ ++// 测试 engine_get_summary 函数 ++TEST_F(EngineDeviceTest, engine_get_summary) { ++ // 准备一些测试数据 ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ device->m_dev.Percentage = 50.0; ++ device->m_dev.TimeToEmpty = 100; ++ m_pEngineDeviceDbus->devices.append(device); ++ QString summary = m_pEngineDeviceDbus->engine_get_summary(); ++ // 检查返回的摘要是否符合预期 ++ EXPECT_FALSE(summary.isEmpty()); ++ ++ ++ delete device; ++} ++ ++ ++// 测试 engine_get_device_summary 函数 ++TEST_F(EngineDeviceTest, engine_get_device_summary) { ++ // 准备一些测试数据 ++ DEVICE *device = new DEVICE; ++ device->m_dev.IsPresent = true; ++ device->m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device->m_dev.State = UP_DEVICE_STATE_CHARGING; ++ device->m_dev.Percentage = 50.0; ++ device->m_dev.TimeToEmpty = 100; ++ QString summary = m_pEngineDeviceDbus->engine_get_device_summary(device); ++ // 检查返回的摘要是否符合预期 ++ EXPECT_FALSE(summary.isEmpty()); ++ ++ ++ delete device; ++} ++ ++ ++// 测试 engine_kind_to_localised_text 函数 ++TEST_F(EngineDeviceTest, engine_kind_to_localised_text) { ++ EXPECT_EQ(m_pEngineDeviceDbus->engine_kind_to_localised_text(UP_DEVICE_KIND_LINE_POWER, 0), "AC adapter"); ++ EXPECT_EQ(m_pEngineDeviceDbus->engine_kind_to_localised_text(UP_DEVICE_KIND_BATTERY, 0), "Laptop battery"); ++ // 测试其他枚举值 ++} ++ ++const static QString upowerService = QStringLiteral("org.freedesktop.UPower"); ++const static QString upowerPath = QStringLiteral("/org/freedesktop/UPower"); ++const static QString upowerInterface = QStringLiteral("org.freedesktop.UPower"); ++const static QString propertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties"); ++const static QString upowerDisplayPath = QStringLiteral("/org/freedesktop/UPower/devices/DisplayDevice"); ++const static QString upowerDeviceInterface = QStringLiteral("org.freedesktop.UPower.Device"); ++ ++// 测试 UpowerHelper 类 ++class UpowerHelperTest : public ::testing::Test { ++protected: ++ std::unique_ptr<UpowerHelper> upowerHelper; ++ std::unique_ptr<EngineDevice> engineDevice; ++ ++ ++ void SetUp() override { ++ engineDevice = std::make_unique<EngineDevice>(); ++ upowerHelper = std::make_unique<UpowerHelper>(nullptr); ++ upowerHelper->m_engineDevice = engineDevice.get(); ++ } ++ ++ ++ void TearDown() override { ++ upowerHelper.reset(); ++ engineDevice.reset(); ++ } ++}; ++ ++ ++// 测试 UpowerHelper 构造函数中的 DBus 连接和属性初始化 ++TEST_F(UpowerHelperTest, UpowerHelperConstructor) { ++ // 检查 m_upowerService 是否有效 ++ EXPECT_TRUE(upowerHelper->m_upowerService->isValid()); ++ ++ ++ // 检查 m_upowerInterface 是否有效 ++ EXPECT_TRUE(upowerHelper->m_upowerInterface->isValid()); ++ ++ ++ // 检查是否正确连接了信号 ++// QDBusConnectionInterface *connectionInterface = QDBusConnection::systemBus().interface(); ++// bool isConnected = connectionInterface->isConnected(upowerService, upowerPath, propertiesInterface, "PropertiesChanged", upowerHelper.get()); ++// EXPECT_TRUE(isConnected); ++ ++ ++ // 检查 m_isBattery 的初始化 ++ QDBusReply<QVariant> interfaceReply = upowerHelper->m_upowerInterface->call("Get", "org.freedesktop.UPower", "LidIsPresent"); ++ bool expectedIsBattery = interfaceReply.isValid()? interfaceReply.value().toBool() : false; ++ EXPECT_EQ(upowerHelper->m_isBattery, expectedIsBattery); ++ ++ ++ // 检查是否正确连接了电池设备的信号 ++// if (!upowerHelper->m_batInterface.isNull()) { ++// isConnected = connectionInterface->isConnected(upowerService, upowerHelper->m_batInterface->path(), propertiesInterface, "PropertiesChanged", upowerHelper.get()); ++// EXPECT_TRUE(isConnected); ++// } ++ ++ ++ // 检查是否正确连接了 EngineDevice 的信号 ++ bool isSignalConnected = QObject::connect(engineDevice.get(), &EngineDevice::engine_signal_Battery_State, upowerHelper.get(), &UpowerHelper::onBatteryChanged); ++ EXPECT_TRUE(isSignalConnected); ++} ++ ++ ++// 测试 getBatteryIconName 函数 ++TEST_F(UpowerHelperTest, GetBatteryIconName) { ++ // 模拟电池状态和百分比 ++ upowerHelper->m_upowerInterface->setProperty("OnBattery", QVariant(true)); ++ upowerHelper->m_batInterface->setProperty("Percentage", QVariant(50.0)); ++ ++ ++ QString iconName = upowerHelper->getBatteryIconName(); ++ EXPECT_EQ(iconName, "battery-level-50-symbolic"); ++ ++ ++ upowerHelper->m_upowerInterface->setProperty("OnBattery", QVariant(false)); ++ iconName = upowerHelper->getBatteryIconName(); ++ EXPECT_EQ(iconName, "battery-level-50-charging-symbolic"); ++ ++ ++ // 测试异常情况,如百分比为负数 ++ upowerHelper->m_batInterface->setProperty("Percentage", QVariant(-10.0)); ++ iconName = upowerHelper->getBatteryIconName(); ++ EXPECT_EQ(iconName, "battery-level--10-symbolic"); ++ ++ ++ // 测试无效的 DBus 接口 ++// upowerHelper->m_upowerService->setValid(false); ++ iconName = upowerHelper->getBatteryIconName(); ++ EXPECT_EQ(iconName, QString()); ++} ++ ++ ++// 测试 getBatteryArgs 函数 ++TEST_F(UpowerHelperTest, GetBatteryArgs) { ++ // 模拟 engineDevice 的状态 ++ DEVICE device; ++ device.m_dev.IsPresent = true; ++ device.m_dev.kind = UP_DEVICE_KIND_BATTERY; ++ device.m_dev.State = UP_DEVICE_STATE_CHARGING; ++ engineDevice->devices.append(&device); ++ ++ ++ QStringList args = upowerHelper->getBatteryArgs(); ++ ++ ++ // 检查是否调用了 engine_get_state 并得到了正确的结果 ++ EXPECT_FALSE(args.isEmpty()); ++ ++ ++ // 测试 engineDevice 为空的情况 ++ upowerHelper->m_engineDevice = nullptr; ++ args = upowerHelper->getBatteryArgs(); ++ EXPECT_TRUE(args.isEmpty()); ++} ++ ++ ++// 测试 onBatteryChanged 函数 ++TEST_F(UpowerHelperTest, OnBatteryChanged) { ++ QStringList args = {"arg1", "arg2"}; ++ ++ ++ // 使用 QSignalSpy 监听 batteryChanged 信号 ++ QSignalSpy spy(upowerHelper.get(), SIGNAL(batteryChanged(QStringList))); ++ ++ ++ upowerHelper->onBatteryChanged(args); ++ ++ ++// 检查信号是否正确触发 ++ EXPECT_EQ(spy.count(), 1); ++ EXPECT_EQ(spy[0][0].toStringList(), args); ++} ++ ++ ++// 测试 dealMessage 函数 ++TEST_F(UpowerHelperTest, DealMessage) { ++ // 使用 QSignalSpy 监听 batteryStatusChanged 信号 ++ QSignalSpy spy(upowerHelper.get(), SIGNAL(batteryStatusChanged(QString))); ++ ++ ++ QDBusMessage message; ++ ++ ++ upowerHelper->dealMessage(message); ++ ++ ++// // 检查信号是否正确触发 ++ EXPECT_EQ(spy.count(), 1); ++ ++ ++ // 测试信号传递的参数 ++ upowerHelper->m_upowerService->setProperty("OnBattery", QVariant(true)); ++ upowerHelper->m_batInterface->setProperty("Percentage", QVariant(30.0)); ++ upowerHelper->dealMessage(message); ++ EXPECT_EQ(spy[1][0].toString(), "battery-level-30-symbolic"); ++} ++ ++ ++// 测试 onLidWatcherMessage 函数 ++TEST_F(UpowerHelperTest, OnLidWatcherMessage) { ++ // 使用 QSignalSpy 监听 lidStateChanged 信号 ++ QSignalSpy spy(upowerHelper.get(), SIGNAL(lidStateChanged(bool))); ++ ++ ++ QDBusMessage message; ++ ++ ++ upowerHelper->onLidWatcherMessage(); ++ ++ ++ // 检查信号是否正确触发 ++ EXPECT_EQ(spy.count(), 1); ++ ++ ++ // 测试信号传递的参数 ++ QDBusInterface iface(upowerService, upowerPath, propertiesInterface, QDBusConnection::systemBus()); ++ iface.setProperty("LidIsClosed", QVariant(true)); ++ upowerHelper->onLidWatcherMessage(); ++ EXPECT_EQ(spy[1][0].toBool(), true); ++ ++ ++ iface.setProperty("LidIsClosed", QVariant(false)); ++ upowerHelper->onLidWatcherMessage(); ++ EXPECT_EQ(spy[2][0].toBool(), false); ++} ++ ++ ++ ++ +diff --git a/tests/unit_test_freedesktop_helper/CMakeLists.txt b/tests/unit_test_freedesktop_helper/CMakeLists.txt +new file mode 100644 +index 0000000..2ad8965 +--- /dev/null ++++ b/tests/unit_test_freedesktop_helper/CMakeLists.txt +@@ -0,0 +1,58 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/freedesktophelper.cpp ++ unit_test_freedesktop_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/dbusifs/freedesktophelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_freedesktop_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_freedesktop_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_freedesktop_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_freedesktop_helper/main.cpp b/tests/unit_test_freedesktop_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_freedesktop_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp b/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp +new file mode 100644 +index 0000000..d355a17 +--- /dev/null ++++ b/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp +@@ -0,0 +1,38 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/freedesktophelper.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class FreedesktopHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pFreedesktopHelperDbus = new FreedesktopHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pFreedesktopHelperDbus; ++ m_pFreedesktopHelperDbus = nullptr; ++ } ++ ++ static FreedesktopHelper *m_pFreedesktopHelperDbus; ++}; ++ ++FreedesktopHelper *FreedesktopHelperTest::m_pFreedesktopHelperDbus = nullptr; ++ ++TEST_F(FreedesktopHelperTest, NameHasOwner) ++{ ++ bool value = m_pFreedesktopHelperDbus->NameHasOwner("org.ukui.Biometric"); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(FreedesktopHelperTest, isServiceActivable) ++{ ++ bool value = m_pFreedesktopHelperDbus->isServiceActivable("org.ukui.UniauthBackend"); ++ ASSERT_EQ(value, false); ++} +diff --git a/tests/unit_test_gsettings_helper/CMakeLists.txt b/tests/unit_test_gsettings_helper/CMakeLists.txt +new file mode 100644 +index 0000000..0c8fcfa +--- /dev/null ++++ b/tests/unit_test_gsettings_helper/CMakeLists.txt +@@ -0,0 +1,63 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/gsettingshelper.cpp ++ unit_test_gsettings_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/lock-backend/gsettingshelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_gsettings_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_gsettings_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ ${QGS_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_gsettings_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) +diff --git a/tests/unit_test_gsettings_helper/main.cpp b/tests/unit_test_gsettings_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_gsettings_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp b/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp +new file mode 100644 +index 0000000..ed02904 +--- /dev/null ++++ b/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp +@@ -0,0 +1,437 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/lock-backend/gsettingshelper.h" ++#include "../../src/common/definetypes.h" ++ ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class GSettingsHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pGSettingsHelperDbus = new GSettingsHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pGSettingsHelperDbus; ++ m_pGSettingsHelperDbus = nullptr; ++ } ++ ++ static GSettingsHelper *m_pGSettingsHelperDbus; ++}; ++ ++GSettingsHelper *GSettingsHelperTest::m_pGSettingsHelperDbus = nullptr; ++ ++TEST_F(GSettingsHelperTest, GetScreenSaverConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_REST_TIME); ++ bool value1 = result1.toBool(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_REST_TIME); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME); ++ bool value2 = result2.toBool(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_CUSTOM_REST_TIME); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME); ++ bool value3 = result3.toBool(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_UKUI_REST_TIME); ++ ++ QVariant result4 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_CYCLE_TIME); ++ int value4 = result4.toInt(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_CYCLE_TIME); ++ ++ QVariant result5 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE); ++ bool value5 = result5.toBool(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_AUTOMATIC_SWITCHING_ENABLE); ++ ++ QVariant result6 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_BACKGROUND_PATH); ++ QString value6 = result6.toString(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_BACKGROUND_PATH); ++ ++ QVariant result7 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_MYTEXT); ++ QString value7 = result7.toString(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_MYTEXT); ++ ++ QVariant result8 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_TEXT_IS_CENTER); ++ bool value8 = result8.toBool(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_TEXT_IS_CENTER); ++ ++ QVariant result9 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_MESSAGE_ENABLED); ++ bool value9 = result9.toBool(); ++ ++ QVariant result10 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_MESSAGE_NUMBER); ++ int value10 = result10.toInt(); ++ ++ QVariant result11 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_FORMAT); ++ QString value11 = result11.toString(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_FORMAT); ++ ++ QVariant result12 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_PATH); ++ QString value12 = result12.toString(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_PATH); ++ ++ QVariant result13 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_SIZE); ++ int value13 = result13.toInt(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_SIZE); ++ ++ QVariant result14 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_WIDTH); ++ int value14 = result14.toInt(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_WIDTH); ++ ++ QVariant result15 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_HEIGHT); ++ int value15 = result15.toInt(); ++ m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_HEIGHT); ++ ++ ASSERT_EQ(value1, true); ++ ASSERT_EQ(value2, true); ++ ASSERT_EQ(value3, true); ++ ASSERT_EQ(value4, 300); ++ ASSERT_EQ(value5, false); ++ ASSERT_EQ(value6.isEmpty(), false); ++ ASSERT_EQ(value7.isEmpty(), true); ++ ASSERT_EQ(value8, true); ++ ASSERT_EQ(value9, false); ++ ASSERT_EQ(value10, 0); ++ ASSERT_EQ(value11.isEmpty(), false); ++ ASSERT_EQ(value12.isEmpty(), false); ++ ASSERT_EQ(value13, 100); ++ ASSERT_EQ(value14, 1920); ++ ASSERT_EQ(value15, 1080); ++} ++ ++TEST_F(GSettingsHelperTest, SetScreenSaverConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_REST_TIME); ++ bool oldValue = result.toBool(); ++ ++ bool value = m_pGSettingsHelperDbus->SetScreenSaverConf(KEY_SHOW_REST_TIME, true); ++ ++ m_pGSettingsHelperDbus->SetScreenSaverConf(KEY_SHOW_REST_TIME, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetLockScreenConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_DELAY); ++ int value1 = result1.toInt(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_DELAY); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK); ++ int value2 = result2.toInt(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK); ++ bool value3 = result3.toBool(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK); ++ ++ QVariant result4 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK); ++ bool value4 = result4.toBool(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK); ++ ++ QVariant result5 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK); ++ int value5 = result5.toInt(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK); ++ ++ QVariant result6 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK); ++ bool value6 = result6.toBool(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK); ++ ++ QVariant result7 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_SLEEP_ACTIVATION_ENABLED); ++ bool value7 = result7.toBool(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_SLEEP_ACTIVATION_ENABLED); ++ ++ QVariant result8 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_LOCK_ENABLED); ++ bool value8 = result8.toBool(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_LOCK_ENABLED); ++ ++ QVariant result9 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_BACKGROUND); ++ QString value9 = result9.toString(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_BACKGROUND); ++ ++ QVariant result10 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_MODE); ++ QString value10 = result10.toString(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_MODE); ++ ++ QVariant result11 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_THEMES); ++ QStringList value11 = result11.toStringList(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_THEMES); ++ ++ QVariant result12 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IMAGE_TRANSITION_EFFECT); ++ int value12 = result12.toInt(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IMAGE_TRANSITION_EFFECT); ++ ++ QVariant result13 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IMAGE_SWITCH_INTERVAL); ++ int value13 = result13.toInt(); ++ m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IMAGE_SWITCH_INTERVAL); ++ ++ ASSERT_EQ(value1, 5); ++ ASSERT_EQ(value2, -1); ++ ASSERT_EQ(value3, true); ++ ASSERT_EQ(value4, true); ++ ASSERT_EQ(value5, 10); ++ ASSERT_EQ(value6, true); ++ ASSERT_EQ(value7, true); ++ ASSERT_EQ(value8, true); ++ ASSERT_EQ(value9.isEmpty(), false); ++ ASSERT_EQ(value10.isEmpty(), false); ++ ASSERT_EQ(value11.isEmpty(), false); ++ ASSERT_EQ(value12, 0); ++ ASSERT_EQ(value13, 60); ++} ++ ++TEST_F(GSettingsHelperTest, SetLockScreenConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_DELAY); ++ int oldValue = result.toInt(); ++ ++ bool value = m_pGSettingsHelperDbus->SetLockScreenConf(KEY_IDLE_DELAY, 1); ++ m_pGSettingsHelperDbus->SetLockScreenConf(KEY_IDLE_DELAY, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetPowerManagerConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_SUSPEND); ++ bool value1 = result1.toBool(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_SUSPEND); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_HIBERNATE); ++ bool value2 = result2.toBool(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_HIBERNATE); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_BLANKSCREEN); ++ bool value3 = result3.toBool(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_BLANKSCREEN); ++ ++ QVariant result4 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_SLEEP_COMPUTER_AC); ++ int value4 = result4.toInt(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_SLEEP_COMPUTER_AC); ++ ++ QVariant result5 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_SLEEP_DISPLAY_AC); ++ int value5 = result5.toInt(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_SLEEP_DISPLAY_AC); ++ ++ QVariant result6 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_BUTTON_LID_AC); ++ int value6 = result6.toInt(); ++ m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_BUTTON_LID_AC); ++ ++ ASSERT_EQ(value1, false); ++ ASSERT_EQ(value2, false); ++ ASSERT_EQ(value3, true); ++ ASSERT_EQ(value4, -1); ++ ASSERT_EQ(value5, -1); ++ ASSERT_EQ(value6, 0); ++} ++ ++TEST_F(GSettingsHelperTest, SetPowerManagerConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_SUSPEND); ++ bool oldValue = result.toBool(); ++ ++ bool value = m_pGSettingsHelperDbus->SetPowerManagerConf(KEY_LOCK_SUSPEND, false); ++ m_pGSettingsHelperDbus->SetPowerManagerConf(KEY_LOCK_SUSPEND, oldValue); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetMateBgConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_FILENAME); ++ QString value1 = result1.toString(); ++// m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PICTURE_FILENAME); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_OPTIONS); ++ QString value2 = result2.toString(); ++// m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PICTURE_OPTIONS); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PRIMARY_COLOR); ++ QString value3 = result3.toString(); ++// m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PRIMARY_COLOR); ++ ++ ASSERT_EQ(value1.isEmpty(), false); ++ ASSERT_EQ(value2.isEmpty(), false); ++ ASSERT_EQ(value3.isEmpty(), false); ++} ++ ++TEST_F(GSettingsHelperTest, SetMateBgConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_FILENAME); ++ QString oldValue = result.toString(); ++ ++ bool value = m_pGSettingsHelperDbus->SetMateBgConf(KEY_PICTURE_FILENAME, "ssss"); ++ m_pGSettingsHelperDbus->SetMateBgConf(KEY_PICTURE_FILENAME, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetUkccPluginsConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_HOUR_SYSTEM); ++ int value1 = result1.toInt(); ++ m_pGSettingsHelperDbus->onUkccPluginsConfigChanged(KEY_HOUR_SYSTEM); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_DATE); ++ QString value2 = result2.toString(); ++ m_pGSettingsHelperDbus->onUkccPluginsConfigChanged(KEY_DATE); ++ ++ ASSERT_EQ(value1, 24); ++ ASSERT_EQ(value2.isEmpty(), false); ++} ++ ++TEST_F(GSettingsHelperTest, SetUkccPluginsConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_HOUR_SYSTEM); ++ int oldValue = result.toInt(); ++ ++ bool value = m_pGSettingsHelperDbus->SetUkccPluginsConf(KEY_HOUR_SYSTEM, 100); ++ m_pGSettingsHelperDbus->SetUkccPluginsConf(KEY_HOUR_SYSTEM, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetThemeStyleConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE); ++ double value1 = result1.toDouble(); ++ m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT_SIZE); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_THEME_COLOR); ++ QString value2 = result2.toString(); ++ m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_THEME_COLOR); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_MENU_TRANSPARENCY); ++ int value3 = result3.toInt(); ++ m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_MENU_TRANSPARENCY); ++ ++ QVariant result4 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_STYLE_NAME); ++ QString value4 = result4.toString(); ++ m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_STYLE_NAME); ++ ++ QVariant result5 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT); ++ QString value5 = result5.toString(); ++ m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT); ++ ++ ASSERT_EQ(value1, 11); ++ ASSERT_EQ(value2.isEmpty(), false); ++ ASSERT_EQ(value3, 35); ++ ASSERT_EQ(value4.isEmpty(), false); ++ ASSERT_EQ(value5.isEmpty(), false); ++} ++ ++TEST_F(GSettingsHelperTest, SetThemeStyleConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE); ++ int oldValue = result.toInt(); ++ ++ bool value = m_pGSettingsHelperDbus->SetThemeStyleConf(KEY_SYSTEM_FONT_SIZE, 14); ++ m_pGSettingsHelperDbus->SetThemeStyleConf(KEY_SYSTEM_FONT_SIZE, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetSessionConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_IDLE); ++ int value1 = result1.toInt(); ++ m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_IDLE); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC); ++ bool value2 = result2.toBool(); ++ m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_LOGOUT_MUSIC); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_POWEROFF_MUSIC); ++ bool value3 = result3.toBool(); ++ m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_POWEROFF_MUSIC); ++ ++ ASSERT_EQ(value1, 1); ++ ASSERT_EQ(value2, false); ++ ASSERT_EQ(value3, false); ++} ++ ++TEST_F(GSettingsHelperTest, SetSessionConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC); ++ bool oldValue = result.toBool(); ++ ++ bool value = m_pGSettingsHelperDbus->SetSessionConf(KEY_SESSION_LOGOUT_MUSIC, false); ++ m_pGSettingsHelperDbus->SetSessionConf(KEY_SESSION_LOGOUT_MUSIC, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetKeyboardConf) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetKeyboardConf(KEY_CAPSLOCK_STATUS); ++ bool value1 = result1.toBool(); ++ m_pGSettingsHelperDbus->onKeyboardConfigChanged(KEY_CAPSLOCK_STATUS); ++ ASSERT_EQ(value1, false); ++} ++ ++TEST_F(GSettingsHelperTest, SetKeyboardConf) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetKeyboardConf(KEY_CAPSLOCK_STATUS); ++ bool oldValue = result.toBool(); ++ ++ bool value = m_pGSettingsHelperDbus->SetKeyboardConf(KEY_CAPSLOCK_STATUS, false); ++ m_pGSettingsHelperDbus->SetKeyboardConf(KEY_CAPSLOCK_STATUS, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(GSettingsHelperTest, GetUsdMediaKeys) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_AREA_SCREENSHOT); ++ QString value1 = result1.toString(); ++ m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT); ++ ++ QVariant result2 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_AREA_SCREENSHOT2); ++ QString value2 = result2.toString(); ++ m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT2); ++ ++ QVariant result3 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_SCREEN_SHOT); ++ QString value3 = result3.toString(); ++ m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_SCREEN_SHOT); ++ ++ QVariant result4 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_SCREEN_SHOT2); ++ QString value4 = result4.toString(); ++ m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_SCREEN_SHOT2); ++ ++ QVariant result5 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_WINDOW_SCREENSHOT); ++ QString value5 = result5.toString(); ++ m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_WINDOW_SCREENSHOT); ++ ++ ASSERT_EQ(value1.isEmpty(), false); ++ ASSERT_EQ(value2.isEmpty(), false); ++ ASSERT_EQ(value3.isEmpty(), false); ++ ASSERT_EQ(value4.isEmpty(), false); ++ ASSERT_EQ(value5.isEmpty(), false); ++} ++ ++TEST_F(GSettingsHelperTest, GetUsdMediaStateKeys) ++{ ++ QVariant result1 = m_pGSettingsHelperDbus->GetUsdMediaStateKeys(KEY_RFKILL_STATE); ++ bool value1 = result1.toBool(); ++ m_pGSettingsHelperDbus->onUsdMediaStateKeysConfigChanged(KEY_RFKILL_STATE); ++ ASSERT_EQ(value1, false); ++} ++ ++TEST_F(GSettingsHelperTest, SetUsdMediaStateKeys) ++{ ++ QVariant result = m_pGSettingsHelperDbus->GetUsdMediaStateKeys(KEY_RFKILL_STATE); ++ bool oldValue = result.toBool(); ++ ++ bool value = m_pGSettingsHelperDbus->SetUsdMediaStateKeys(KEY_RFKILL_STATE, false); ++ m_pGSettingsHelperDbus->SetUsdMediaStateKeys(KEY_RFKILL_STATE, oldValue); ++ ++ ASSERT_EQ(value, true); ++} ++ ++ ++ ++ +diff --git a/tests/unit_test_inputswitch_event/CMakeLists.txt b/tests/unit_test_inputswitch_event/CMakeLists.txt +new file mode 100644 +index 0000000..d0da1cf +--- /dev/null ++++ b/tests/unit_test_inputswitch_event/CMakeLists.txt +@@ -0,0 +1,63 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/libinputswitchevent.cpp ++ ../../src/dbusifs/machinemodel.cpp ++ unit_test_inputswitch_event.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/dbusifs/libinputswitchevent.h ++ ../../src/dbusifs/machinemodel.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_inputswitch_event ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_inputswitch_event ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ ${QGS_LIBRARIES} ++ -lukuiinputgatherclient ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_inputswitch_event ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_inputswitch_event/main.cpp b/tests/unit_test_inputswitch_event/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_inputswitch_event/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp b/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp +new file mode 100644 +index 0000000..5d4fbba +--- /dev/null ++++ b/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp +@@ -0,0 +1,137 @@ ++#include <gtest/gtest.h> ++#include <QCoreApplication> ++#include <QString> ++#include <memory> ++#include <iostream> ++#include "../../src/dbusifs/libinputswitchevent.h" ++#include "../../src/dbusifs/machinemodel.h" ++ ++ ++// 辅助函数,模拟文件读取内容 ++QString simulateFileRead(const QString &filePath) { ++ if (filePath == "/sys/class/dmi/id/sys_vendor") { ++ return "Vendor"; ++ } else if (filePath == "/sys/class/dmi/id/product_name") { ++ return "Product"; ++ } else if (filePath == "/sys/class/dmi/id/product_family") { ++ return "Family"; ++ } ++ return ""; ++} ++ ++ ++// 测试 MachineModel 类 ++class MachineModelTest : public ::testing::Test { ++protected: ++ std::shared_ptr<MachineModel> machineModel; ++ ++ ++ void SetUp() override { ++ machineModel = MachineModel::getMachineModelInstance(); ++ } ++ ++ ++ void TearDown() override { ++ machineModel.reset(); ++ } ++}; ++ ++ ++// 测试 getSysVendor 函数 ++TEST_F(MachineModelTest, getSysVendor) { ++ QString vendor = machineModel->getSysVendor(); ++ EXPECT_EQ(vendor, "Vendor"); ++} ++ ++ ++// 测试 getProductName 函数 ++TEST_F(MachineModelTest, getProductName) { ++ QString productName = machineModel->getProductName(); ++ EXPECT_EQ(productName, "Product"); ++} ++ ++ ++// 测试 getProductFamily 函数 ++TEST_F(MachineModelTest, getProductFamily) { ++ QString productFamily = machineModel->getProductFamily(); ++ EXPECT_EQ(productFamily, "Family"); ++} ++ ++ ++// 测试 initMachineType 函数 ++TEST_F(MachineModelTest, initMachineType) { ++ machineModel->initMachineType(); ++ QString machineType = machineModel->getTheMachineType(); ++ EXPECT_EQ(machineType, ""); // 这里根据实际的配置文件设置进行调整 ++} ++ ++ ++// 测试 LibinputSwitchEvent 类 ++class LibinputSwitchEventTest : public ::testing::Test { ++protected: ++ std::unique_ptr<LibinputSwitchEvent> libinputSwitchEvent; ++ ++ ++ void SetUp() override { ++ // 使用模拟的 QProcess ++ qputenv("QT_QPA_PLATFORM", "minimal"); ++ qRegisterMetaType<Event *>("Event*"); ++ libinputSwitchEvent = std::make_unique<LibinputSwitchEvent>(nullptr); ++ } ++ ++ ++ void TearDown() override { ++ libinputSwitchEvent.reset(); ++ } ++}; ++ ++ ++// 测试 geInitDevicesStatus 函数 ++TEST_F(LibinputSwitchEventTest, geInitDevicesStatus) { ++ // 测试不同的机器类型 ++ libinputSwitchEvent->m_machineType = "SLATE"; ++ EXPECT_TRUE(libinputSwitchEvent->geInitDevicesStatus()); ++ ++ ++ libinputSwitchEvent->m_machineType = "LAPTOP"; ++ // EXPECT_TRUE(libinputSwitchEvent->geInitDevicesStatus()); ++ ++ ++ libinputSwitchEvent->m_machineType = "ALLINONE"; ++ EXPECT_FALSE(libinputSwitchEvent->geInitDevicesStatus()); ++ ++ ++ libinputSwitchEvent->m_machineType = "OTHER"; ++ EXPECT_FALSE(libinputSwitchEvent->geInitDevicesStatus()); ++} ++ ++ ++// 测试 dealEvent 函数 ++TEST_F(LibinputSwitchEventTest, dealEvent) { ++ Event event; ++ event.type = LIBINPUT_EVENT_SWITCH_TOGGLE; ++ event.event.switchEventDate.switchType = LIBINPUT_SWITCH_TABLET_MODE; ++ ++ ++ // 测试切换到平板模式 ++// event.event.switchEventDate.switchState = LIBINPUT_SWITCH_STATE_ON; ++// QSignalSpy spy(libinputSwitchEvent.get(), SIGNAL(tabletModeStatusChanged(int))); ++// libinputSwitchEvent->dealEvent(&event); ++// EXPECT_EQ(spy.count(), 1); ++// EXPECT_EQ(spy[0][0].value<int>(), 1); ++ ++ ++// // 测试切换出平板模式 ++// event.event.switchEventDate.switchState = LIBINPUT_SWITCH_STATE_OFF; ++// spy.clear(); ++// libinputSwitchEvent->dealEvent(&event); ++// EXPECT_EQ(spy.count(), 1); ++// EXPECT_EQ(spy[0][0].value<int>(), 0); ++ ++ ++ // 测试其他事件类型 ++// event.type = LIBINPUT_EVENT_NONE; ++// spy.clear(); ++// libinputSwitchEvent->dealEvent(&event); ++// EXPECT_EQ(spy.count(), 0); ++} +diff --git a/tests/unit_test_kglobalaccel_helper/CMakeLists.txt b/tests/unit_test_kglobalaccel_helper/CMakeLists.txt +new file mode 100644 +index 0000000..8c28b68 +--- /dev/null ++++ b/tests/unit_test_kglobalaccel_helper/CMakeLists.txt +@@ -0,0 +1,57 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/kglobalaccelhelper.cpp ++ unit_test_kglobalaccel_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/dbusifs/kglobalaccelhelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_kglobalaccel_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_kglobalaccel_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_kglobalaccel_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_kglobalaccel_helper/main.cpp b/tests/unit_test_kglobalaccel_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_kglobalaccel_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp b/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp +new file mode 100644 +index 0000000..11def17 +--- /dev/null ++++ b/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp +@@ -0,0 +1,36 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/kglobalaccelhelper.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class KglobalAccelHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pKglobalAccelHelperDbus = new KglobalAccelHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pKglobalAccelHelperDbus; ++ m_pKglobalAccelHelperDbus = nullptr; ++ } ++ ++ static KglobalAccelHelper *m_pKglobalAccelHelperDbus; ++}; ++ ++KglobalAccelHelper *KglobalAccelHelperTest::m_pKglobalAccelHelperDbus = nullptr; ++ ++TEST_F(KglobalAccelHelperTest, blockShortcut) ++{ ++ bool oldValue = m_pKglobalAccelHelperDbus->blockShortcut(true); ++ ASSERT_EQ(oldValue, true); ++ ++ bool newValue = m_pKglobalAccelHelperDbus->blockShortcut(false); ++ ASSERT_EQ(newValue, true); ++} ++ +diff --git a/tests/unit_test_lock_dialog_model/CMakeLists.txt b/tests/unit_test_lock_dialog_model/CMakeLists.txt +new file mode 100644 +index 0000000..db1fa6d +--- /dev/null ++++ b/tests/unit_test_lock_dialog_model/CMakeLists.txt +@@ -0,0 +1,86 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Widgets X11Extras Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++find_package(X11 REQUIRED) ++ ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++pkg_check_modules(XCB REQUIRED xcb) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-dialog/lockdialogmodel.cpp ++ ../../src/userinfo.cpp ++ ../../src/agreementinfo.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/common/global_utils.cpp ++ ../..//src/widgets/screensavermode.cpp ++ ../../src/common/utils.cpp ++ unit_test_lock_dialog_model.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-dialog/lockdialogmodel.h ++ ../../src/common/definetypes.h ++ ../../src/common/biodefines.h ++ ../../src/userinfo.h ++ ../../src/agreementinfo.h ++ ../../src/common/global_utils.h ++ ../..//src/widgets/screensavermode.h ++ ../../src/common/utils.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${X11_INCLUDE_DIRS} ++ ${XCB_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_lock_dialog_model ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_lock_dialog_model ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::Widgets ++ Qt5::X11Extras ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_lock_dialog_model ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++ ${GIOUNIX2_LIBRARIES} ++ ${X11_LIBRARIES} ++ ${XCB_LIBRARIES} ++) ++ +diff --git a/tests/unit_test_lock_dialog_model/main.cpp b/tests/unit_test_lock_dialog_model/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_lock_dialog_model/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp b/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp +new file mode 100644 +index 0000000..32db3a1 +--- /dev/null ++++ b/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp +@@ -0,0 +1,68 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include <QCommandLineParser> ++#include <QDebug> ++ ++#include "../../src/lock-dialog/lockdialogmodel.h" ++#include "../../src/common/definetypes.h" ++#include "../../src/agreementinfo.h" ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++// 测试夹具类,用于初始化和清理测试环境 ++class LockDialogModelTest : public ::testing::Test { ++protected: ++ LockDialogModel* model; ++ ++ virtual void SetUp() { ++ model = new LockDialogModel(nullptr); ++ } ++ ++ virtual void TearDown() { ++ delete model; ++ } ++}; ++ ++TEST_F(LockDialogModelTest, ParseCmdArguments) { ++ QStringList args; ++ LockDialogModel::CommandLineArgs cmdArgs; ++ ++ // 天翼云情况测试(模拟天翼云平台) ++ args << "--lock-startup"; ++ setenv("HostCloundPlatform", "ctyun", 1); ++ EXPECT_TRUE(model->parseCmdArguments(args, cmdArgs)); ++ unsetenv("HostCloundPlatform"); ++ ++ // 非天翼云且参数不全情况测试 ++ args.clear(); ++// EXPECT_FALSE(model->parseCmdArguments(args, cmdArgs)); ++ ++ // 完整参数设置测试 ++ args << "--lock"; ++ EXPECT_TRUE(model->parseCmdArguments(args, cmdArgs)); ++ EXPECT_TRUE(cmdArgs.isLock); ++} ++ ++TEST_F(LockDialogModelTest, FindUserByName) { ++ ++ // 查找已存在的用户 ++ UserInfoPtr result = model->findUserByName("testuser"); ++ EXPECT_NE(result, nullptr); ++ ++ // 查找不存在的用户 ++ result = model->findUserByName("nonexistentuser"); ++ EXPECT_EQ(result, nullptr); ++} ++ ++TEST_F(LockDialogModelTest, GetScreensaver) { ++ ++ ScreenSaver* saver = model->getScreensaver(); ++ EXPECT_EQ(saver->mode, SAVER_RANDOM); ++ delete saver; ++ ++ saver = model->getScreensaver(); ++ EXPECT_EQ(saver->mode, SAVER_IMAGE); ++ delete saver; ++} ++ +diff --git a/tests/unit_test_login1_helper/CMakeLists.txt b/tests/unit_test_login1_helper/CMakeLists.txt +new file mode 100644 +index 0000000..4263e43 +--- /dev/null ++++ b/tests/unit_test_login1_helper/CMakeLists.txt +@@ -0,0 +1,58 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/login1helper.cpp ++ unit_test_login1_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/dbusifs/login1helper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_login1_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_login1_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_login1_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_login1_helper/main.cpp b/tests/unit_test_login1_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_login1_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_login1_helper/unit_test_login1_helper.cpp b/tests/unit_test_login1_helper/unit_test_login1_helper.cpp +new file mode 100644 +index 0000000..469bbd1 +--- /dev/null ++++ b/tests/unit_test_login1_helper/unit_test_login1_helper.cpp +@@ -0,0 +1,95 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/login1helper.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class Login1HelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pLogin1HelperDbus = new Login1Helper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pLogin1HelperDbus; ++ m_pLogin1HelperDbus = nullptr; ++ } ++ ++ static Login1Helper *m_pLogin1HelperDbus; ++}; ++ ++Login1Helper *Login1HelperTest::m_pLogin1HelperDbus = nullptr; ++ ++TEST_F(Login1HelperTest, isSessionActive) ++{ ++ bool value = m_pLogin1HelperDbus->isSessionActive(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, onPrepareForSleep) ++{ ++ bool oldSleep = m_pLogin1HelperDbus->m_isSleeping; ++ m_pLogin1HelperDbus->onPrepareForSleep(true); ++ m_pLogin1HelperDbus->onHibitedWatcherMessage(); ++ m_pLogin1HelperDbus->onPrepareForSleep(oldSleep); ++ ASSERT_EQ(m_pLogin1HelperDbus->m_isSleeping, true); ++} ++ ++TEST_F(Login1HelperTest, setPowerManager) ++{ ++ m_pLogin1HelperDbus->setPowerManager("test"); ++ m_pLogin1HelperDbus->Unlock(); ++} ++ ++TEST_F(Login1HelperTest, getCanPowerManager) ++{ ++ bool value = m_pLogin1HelperDbus->getCanPowerManager("CanReboot"); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, isCanHibernate) ++{ ++ bool value = m_pLogin1HelperDbus->isCanHibernate(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, isCanSuspend) ++{ ++ bool value = m_pLogin1HelperDbus->isCanSuspend(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, isCanReboot) ++{ ++ bool value = m_pLogin1HelperDbus->isCanReboot(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, isCanPowerOff) ++{ ++ bool value = m_pLogin1HelperDbus->isCanPowerOff(); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(Login1HelperTest, canAction) ++{ ++ bool value = m_pLogin1HelperDbus->canAction(PowerHibernate); ++ bool value1 = m_pLogin1HelperDbus->canAction(PowerSuspend); ++ bool value2 = m_pLogin1HelperDbus->canAction(PowerMonitorOff); ++ bool value3 = m_pLogin1HelperDbus->canAction(PowerLogout); ++ bool value4 = m_pLogin1HelperDbus->canAction(PowerReboot); ++ bool value5 = m_pLogin1HelperDbus->canAction(PowerShutdown); ++ ASSERT_EQ(value, true); ++ ASSERT_EQ(value1, true); ++ ASSERT_EQ(value2, true); ++ ASSERT_EQ(value3, true); ++ ASSERT_EQ(value4, true); ++ ASSERT_EQ(value5, true); ++} ++ ++ +diff --git a/tests/unit_test_personal_data/CMakeLists.txt b/tests/unit_test_personal_data/CMakeLists.txt +new file mode 100644 +index 0000000..a20411e +--- /dev/null ++++ b/tests/unit_test_personal_data/CMakeLists.txt +@@ -0,0 +1,60 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/personalizeddata.cpp ++ unit_test_personal_data.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/personalizeddata.h ++ ) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${LIGHTDM-QT5-3_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_personal_data ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_personal_data ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_personal_data ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++ ${LIGHTDM-QT5-3_LIBRARIES} ++) +diff --git a/tests/unit_test_personal_data/main.cpp b/tests/unit_test_personal_data/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_personal_data/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_personal_data/unit_test_common.cpp b/tests/unit_test_personal_data/unit_test_common.cpp +new file mode 100644 +index 0000000..b350754 +--- /dev/null ++++ b/tests/unit_test_personal_data/unit_test_common.cpp +@@ -0,0 +1,329 @@ ++#include "../../src/common/definetypes.h" ++#include "../../src/common/biodefines.h" ++#include "../../src/common/commonfunc.h" ++#include "../../src/common/configuration.h" ++#include "../../src/common/global_utils.h" ++#include "../../src/common/rsac.h" ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include <QIcon> ++#include <openssl/rsa.h> ++#include <openssl/pem.h> ++#include <openssl/err.h> ++#include <openssl/sha.h> ++#include <iostream> ++#include "../../src/common/rsac.h" ++#include "../../src/common/utils.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++// 辅助函数,用于初始化OpenSSL库 ++ ++void InitOpenSSL() { ++ ++ OpenSSL_add_all_algorithms(); ++ ++ ERR_load_crypto_strings(); ++ ++} ++ ++ ++ ++// 辅助函数,用于清理OpenSSL库 ++ ++void CleanupOpenSSL() { ++ ++ EVP_cleanup(); ++ ++ ERR_free_strings(); ++ ++} ++ ++class CommonTest : public testing::Test ++{ ++protected: ++ ++ void SetUp() override { ++ ++ InitOpenSSL(); ++ ++ } ++ ++ ++ ++ void TearDown() override { ++ ++ CleanupOpenSSL(); ++ ++ } ++ ++ RSAC rsac; ++}; ++ ++TEST_F(CommonTest, scaledPixmap) ++{ ++ setCursorCenter(); ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = scaledPixmap(pixmap); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, PixmapToRound) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = PixmapToRound(pixmap, 4); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, PixmapToRound2) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newPixmap = PixmapToRound(pixmap, 0, 0, 0, 0); ++ ASSERT_EQ(newPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, loadSvg) ++{ ++ QPixmap iconPixmap = loadSvg(":/image/assets/show-password.png", "white", 16); ++ ASSERT_EQ(iconPixmap.isNull(), false); ++} ++ ++TEST_F(CommonTest, drawSymbolicColoredPixmap) ++{ ++ QPixmap retryIcon = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ ASSERT_EQ(drawSymbolicColoredPixmap(retryIcon, "white").isNull(), false); ++ ASSERT_EQ(getLoadingIcon(16).width(), 16); ++} ++ ++TEST_F(CommonTest, scaleBlurPixmap) ++{ ++ QPixmap *pixmap = new QPixmap(scaleBlurPixmap(16, 16, "/usr/share/background/house.png")); ++ ASSERT_EQ(pixmap->width(), 16); ++} ++ ++TEST_F(CommonTest, blurPixmap) ++{ ++ QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48); ++ QPixmap newpixmap = blurPixmap(pixmap); ++ ASSERT_EQ(newpixmap.width(), 16); ++} ++ ++TEST_F(CommonTest, getValue) ++{ ++ if (Configuration::instance()) { ++ QString color = Configuration::instance()->getValue("background-color").toString(); ++ ASSERT_EQ(color.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, getCurrentUser) ++{ ++ if (Configuration::instance()) { ++ Configuration::instance()->getCurrentUser(getenv("USER")); ++ } ++} ++ ++TEST_F(CommonTest, setValue) ++{ ++ if (Configuration::instance()) { ++ QString color = Configuration::instance()->getValue("backgroundPath").toString(); ++ QString oldvalue = Configuration::instance()->getUserConfig("backgroundPath").toString(); ++ Configuration::instance()->setValue("backgroundPath", oldvalue); ++ ASSERT_EQ(oldvalue.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, hasValue) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->hasValue("backgroundPath"); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++ ++TEST_F(CommonTest, getIs990) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->getIs990(); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++TEST_F(CommonTest, getLastNumLock) ++{ ++ if (Configuration::instance()) { ++ bool value = Configuration::instance()->getLastNumLock(); ++ Configuration::instance()->saveLastNumLock(value); ++ ASSERT_EQ(value, false); ++ } ++} ++ ++TEST_F(CommonTest, getRootBackgroundOption) ++{ ++ if (Configuration::instance()) { ++ int value = Configuration::instance()->getRootBackgroundOption(getenv("USER")); ++ ASSERT_EQ(value, 1); ++ } ++} ++ ++TEST_F(CommonTest, getDefaultBackgroundName) ++{ ++ if (Configuration::instance()) { ++ QString background = Configuration::instance()->getDefaultBackgroundName(); ++ ASSERT_EQ(background.isEmpty(), false); ++ } ++} ++ ++TEST_F(CommonTest, checkCapsLockState) ++{ ++ checkIslivecd(); ++ KillFocusOfKydroid(); ++ ASSERT_EQ(checkCapsLockState(), false); ++} ++ ++TEST_F(CommonTest, getDefaultFontSize) ++{ ++ ASSERT_EQ(getDefaultFontSize(), 14.0); ++} ++ ++TEST_F(CommonTest, getUserFontSize) ++{ ++ ASSERT_EQ(getUserFontSize(getenv("USER")), 14.0); ++} ++ ++TEST_F(CommonTest, getUserThemeColor) ++{ ++ ASSERT_EQ(getUserThemeColor(getenv("USER")), "test"); ++} ++ ++// 测试密钥生成并保存到文件 ++ ++TEST_F(CommonTest, GenerateKeyPairToFile) { ++ ++ QString priKeyFile = "test_private.pem"; ++ ++ QString pubKeyFile = "test_public.pem"; ++ ++ rsac.generateKeyPair(priKeyFile, pubKeyFile, 1024); ++ ++ ++ ++ // 这里可以添加额外的检查来验证文件是否成功生成且内容有效 ++ ++ // 例如,打开文件并读取内容,检查是否为有效的PEM格式密钥 ++ ++ // 但由于这是一个简单的测试示例,我们省略了这些步骤 ++ ++ ++ ++ // 清理生成的文件 ++ ++ QFile::remove(priKeyFile); ++ ++ QFile::remove(pubKeyFile); ++ ++} ++ ++ ++ ++// 测试密钥生成并保存到QByteArray ++ ++TEST_F(CommonTest, GenerateKeyPairToByteArray) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ // 检查生成的密钥是否非空 ++ ++ EXPECT_FALSE(privateKey.isEmpty()); ++ ++ EXPECT_FALSE(publicKey.isEmpty()); ++ ++ ++ ++ // 这里可以添加额外的检查来验证密钥的有效性 ++ ++ // 例如,使用OpenSSL函数解析生成的密钥并检查其属性 ++ ++ // 但由于这是一个简单的测试示例,我们省略了这些步骤 ++ ++} ++ ++ ++ ++// 测试加密和解密 ++ ++TEST_F(CommonTest, EncryptDecrypt) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ QByteArray plaintext = "Hello, RSA!"; ++ ++ QByteArray ciphertext; ++ ++ QByteArray decryptedtext; ++ ++ ++ ++ bool encryptResult = rsac.encrypt(plaintext, ciphertext, publicKey); ++ ++ EXPECT_TRUE(encryptResult); ++ ++ ++ ++ bool decryptResult = rsac.decrypt(ciphertext, decryptedtext, privateKey); ++ ++ EXPECT_TRUE(decryptResult); ++ ++ ++ ++ EXPECT_EQ(plaintext, decryptedtext); ++ ++} ++ ++ ++ ++// 测试签名和验签 ++ ++TEST_F(CommonTest, SignVerify) { ++ ++ QByteArray privateKey; ++ ++ QByteArray publicKey; ++ ++ rsac.generateKeyPair(privateKey, publicKey, 1024); ++ ++ ++ ++ QByteArray message = "This is a test message."; ++ ++ QByteArray signature; ++ ++ bool signResult = rsac.sign(message, signature, privateKey); ++ ++ EXPECT_TRUE(signResult); ++ ++ bool verifyResult = rsac.verify(message, signature, publicKey); ++ ++ EXPECT_TRUE(verifyResult); ++ ++ // 尝试使用错误的消息进行验签,应该失败 ++ ++ bool verifyWithWrongMessageResult = rsac.verify("Wrong message.", signature, publicKey); ++ ++ EXPECT_FALSE(verifyWithWrongMessageResult); ++ ++} +diff --git a/tests/unit_test_personal_data/unit_test_personal_data.cpp b/tests/unit_test_personal_data/unit_test_personal_data.cpp +new file mode 100644 +index 0000000..6415f4a +--- /dev/null ++++ b/tests/unit_test_personal_data/unit_test_personal_data.cpp +@@ -0,0 +1,140 @@ ++#include "../../src/lock-backend/personalizeddata.h" ++ ++#include "gtest/gtest.h" ++#include <QJsonObject> ++#include <QJsonDocument> ++#include <QJsonArray> ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++// 测试夹具类,用于初始化和清理测试环境 ++class PersonalizedDataTest : public ::testing::Test { ++protected: ++ PersonalizedData* personalizedData; ++// PersonalizedDataMng* personalizedDataMng; ++ ++ virtual void SetUp() override { ++ personalizedData = new PersonalizedData("testUser"); ++// personalizedDataMng = new PersonalizedDataMng(); ++ } ++ ++ virtual void TearDown() override { ++ delete personalizedData; ++// delete personalizedDataMng; ++ } ++}; ++ ++ ++// 测试 PersonalizedData 类的构造函数和析构函数 ++TEST_F(PersonalizedDataTest, PersonalizedDataConstructorAndDestructor) { ++ // 构造函数应该正确设置用户 ++ KYLINUSERDATAMNG::getInstance()->GetUserPtr(getenv("USER")); ++ KYLINUSERDATAMNG::getInstance()->GetConfInformation(getenv("USER")); ++// KYLINUSERDATAMNG::getInstance()->__getUserInfomation(); ++// EXPECT_EQ(personalizedData->m_user, "testUser"); ++} ++ ++ ++// 测试 PersonalizedData::getJsonData 函数 ++TEST_F(PersonalizedDataTest, PersonalizedDataGetJsonData) { ++ QJsonObject json; ++ personalizedData->getJsonData(json); ++ ++ // 检查生成的 JSON 对象是否包含正确的信息 ++ EXPECT_EQ(json["user"].toString(), "testUser"); ++ EXPECT_EQ(json["dateType"].toString(), "testDateType"); ++ EXPECT_EQ(json["fontSize"].toInt(), 12); ++ EXPECT_EQ(json["timeType"].toInt(), 24); ++ EXPECT_EQ(json["backgroundPath"].toString(), "/path/to/background"); ++ EXPECT_EQ(json["color"].toString(), "red"); ++} ++ ++ ++// 测试 PersonalizedData::setJson 函数 ++TEST_F(PersonalizedDataTest, PersonalizedDataSetJson) { ++ QJsonObject json; ++ json["user"] = "testUser"; ++ json["dateType"] = "newDateType"; ++ json["fontSize"] = 14; ++ json["timeType"] = 12; ++ json["backgroundPath"] = "/new/path/to/background"; ++ json["color"] = "blue"; ++ personalizedData->setJson(json); ++ ++ // 检查属性是否被正确设置 ++// EXPECT_EQ(personalizedData->m_dateType, "newDateType"); ++// EXPECT_EQ(personalizedData->m_fontSize, 14); ++// EXPECT_EQ(personalizedData->m_timeType, 12); ++// EXPECT_EQ(personalizedData->m_backgroundPath, "/new/path/to/background"); ++// EXPECT_EQ(personalizedData->m_color, "blue"); ++} ++ ++ ++//// 测试 PersonalizedDataMng::GetConfInformation 函数 ++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetConfInformation) { ++// // 先添加一些用户信息 ++// personalizedDataMng->m_userPersonalizedData["testUser"] = KylinUserDatePtr(new PersonalizedData("testUser")); ++// personalizedDataMng->m_userPersonalizedData["testUser"]->m_dateType = "testDateType"; ++// personalizedDataMng->m_userPersonalizedData["testUser"]->m_fontSize = 12; ++// personalizedDataMng->m_userPersonalizedData["testUser"]->m_timeType = 24; ++// personalizedDataMng->m_userPersonalizedData["testUser"]->m_backgroundPath = "/path/to/background"; ++// personalizedDataMng->m_userPersonalizedData["testUser"]->m_color = "red"; ++ ++// QString jsonStr = personalizedDataMng->GetConfInformation("testUser"); ++// QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8()); ++// QJsonObject json = doc.object(); ++// QJsonObject userJson = json["testUser"].toObject(); ++ ++// // 检查生成的 JSON 对象是否包含正确的信息 ++// EXPECT_EQ(userJson["greeter"]["dateType"].toString(), "testDateType"); ++// EXPECT_EQ(userJson["greeter"]["fontSize"].toInt(), 12); ++// EXPECT_EQ(userJson["greeter"]["timeType"].toInt(), 24); ++// EXPECT_EQ(userJson["greeter"]["backgroundPath"].toString(), "/path/to/background"); ++// EXPECT_EQ(userJson["greeter"]["color"].toString(), "red"); ++//} ++ ++ ++//// 测试 PersonalizedDataMng::GetUserPtr 函数 ++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetUserPtr) { ++// personalizedDataMng->m_userPersonalizedData["testUser"] = KylinUserDatePtr(new PersonalizedData("testUser")); ++// KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser"); ++// // 检查是否能正确获取用户指针 ++// EXPECT_NE(userPtr, nullptr); ++// EXPECT_EQ(userPtr->m_user, "testUser"); ++//} ++ ++ ++//// 测试 PersonalizedDataMng::updateUserInformation 函数 ++//TEST_F(PersonalizedDataTest, PersonalizedDataMngUpdateUserInformation) { ++// QString jsonString = "{\"user\":\"testUser\",\"operation\":0,\"greeter\":{\"dateType\":\"newDateType\",\"fontSize\":14,\"timeType\":12,\"backgroundPath\":\"/new/path/to/background\",\"color\":\"blue\"}}"; ++// personalizedDataMng->updateUserInformation(jsonString); ++// KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser"); ++// // 检查用户信息是否被正确更新 ++// EXPECT_EQ(userPtr->m_dateType, "newDateType"); ++// EXPECT_EQ(userPtr->m_fontSize, 14); ++// EXPECT_EQ(userPtr->m_timeType, 12); ++// EXPECT_EQ(userPtr->m_backgroundPath, "/new/path/to/background"); ++// EXPECT_EQ(userPtr->m_color, "blue"); ++//} ++ ++ ++//// 测试 PersonalizedDataMng::__getUserInfomation 函数 ++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetUserInfomation) { ++// // 模拟从 DBus 获取的用户信息 ++// QString jsonString = "{\"testUser\":{\"greeter\":{\"dateType\":\"newDateType\",\"fontSize\":14,\"timeType\":12,\"backgroundPath\":\"/new/path/to/background\",\"color\":\"blue\"}}"; ++// QDBusInterface iface( ++// static_dbus_service_name, static_dbus_path, static_dbus_interface, QDBusConnection::systemBus()); ++// QDBusPendingCall pcall; ++// QDBusPendingReply<QString> reply(jsonString); ++// QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, personalizedDataMng); ++// personalizedDataMng->wait_for_finish(watcher); ++// personalizedDataMng->__getUserInfomation(); ++// KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser"); ++// // 检查用户信息是否被正确设置 ++// EXPECT_EQ(userPtr->m_dateType, "newDateType"); ++// EXPECT_EQ(userPtr->m_fontSize, 14); ++// EXPECT_EQ(userPtr->m_timeType, 12); ++// EXPECT_EQ(userPtr->m_backgroundPath, "/new/path/to/background"); ++// EXPECT_EQ(userPtr->m_color, "blue"); ++//} +diff --git a/tests/unit_test_screenlock/CMakeLists.txt b/tests/unit_test_screenlock/CMakeLists.txt +new file mode 100644 +index 0000000..3e91d01 +--- /dev/null ++++ b/tests/unit_test_screenlock/CMakeLists.txt +@@ -0,0 +1,150 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core DBus Network Test REQUIRED) ++find_package(OpenSSL REQUIRED) ++find_package(PkgConfig REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) ++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) ++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量 ++find_library(PAM_LIBRARIES pam) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/authpamthread.cpp ++ ../../src/lock-backend/pamauthenticate.cpp ++ ../../src/lock-backend/lightdmhelper.cpp ++ ../../src/lock-backend/dbusupperinterface.cpp ++ ../../src/lock-backend/gsettingshelper.cpp ++ ../../src/lock-backend/bioauthenticate.cpp ++ ../../src/lock-backend/switchuserutils.cpp ++ ../../src/dbusifs/accountshelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/common/configuration.cpp ++ ../../src/common/rsac.cpp ++ ../../src/dbusifs/giodbus.cpp ++ ../../src/dbusifs/uniauthservice.cpp ++ ../../src/lock-backend/securityuser.cpp ++ ../../src/dbusifs/freedesktophelper.cpp ++ ../../src/dbusifs/login1helper.cpp ++ ../../src/dbusifs/usdhelper.cpp ++ ../../src/dbusifs/upowerhelper.cpp ++ ../../src/dbusifs/sessionhelper.cpp ++ ../../src/dbusifs/dbusservermanager.cpp ++ ../../src/dbusifs/systemupgradehelper.cpp ++ ../../src/lock-backend/sessionwatcher.cpp ++ ../../src/dbusifs/kglobalaccelhelper.cpp ++ ../../src/dbusifs/libinputswitchevent.cpp ++ ../../src/lock-backend/personalizeddata.cpp ++ ../../src/dbusifs/biometrichelper.cpp ++ ../../src/dbusifs/device.cpp ++ ../../src/dbusifs/machinemodel.cpp ++ ../../src/dbusifs/enginedevice.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/QtSingleApplication/qtlocalpeer.cpp ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp ++ ../../src/ukccplugins/sessiondbus/screenlockinterface.cpp ++ unit_test_screenlock.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/authpamthread.h ++ ../../src/lock-backend/pamauthenticate.h ++ ../../src/lock-backend/lightdmhelper.h ++ ../../src/lock-backend/dbusupperinterface.h ++ ../../src/lock-backend/gsettingshelper.h ++ ../../src/lock-backend/bioauthenticate.h ++ ../../src/lock-backend/switchuserutils.h ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/common/configuration.h ++ ../../src/common/rsac.h ++ ../../src/dbusifs/giodbus.h ++ ../../src/dbusifs/accountshelper.h ++ ../../src/common/configuration.h ++ ../../src/dbusifs/uniauthservice.h ++ ../../src/lock-backend/securityuser.h ++ ../../src/dbusifs/freedesktophelper.h ++ ../../src/dbusifs/login1helper.h ++ ../../src/dbusifs/usdhelper.h ++ ../../src/dbusifs/upowerhelper.h ++ ../../src/dbusifs/dbusservermanager.h ++ ../../src/dbusifs/sessionhelper.h ++ ../../src/dbusifs/systemupgradehelper.h ++ ../../src/lock-backend/sessionwatcher.h ++ ../../src/dbusifs/kglobalaccelhelper.h ++ ../../src/dbusifs/libinputswitchevent.h ++ ../../src/lock-backend/personalizeddata.h ++ ../../src/dbusifs/biometrichelper.h ++ ../../src/dbusifs/device.h ++ ../../src/dbusifs/enginedevice.h ++ ../../src/dbusifs/machinemodel.h ++ ../../src/common/biodefines.h ++ ../kt-test-utils/cpp-stub-ext/stubext.h ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.h ++ ../../src/QtSingleApplication/qtlocalpeer.h ++ ../../src/ukccplugins/sessiondbus/screenlockinterface.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${Qt5Test_INCLUDE_DIRS} ++ ${LIGHTDM-QT5-3_INCLUDE_DIRS} ++ ${LIBSYSTEMD_INCLUDE_DIRS} ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/ ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_screenlock ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_screenlock ++ Qt5::Core ++ Qt5::DBus ++ Qt5::Test ++ Qt5::Network ++ ${QGS_LIBRARIES} ++ ${PAM_LIBRARIES} ++ ${LIGHTDM-QT5-3_LIBRARIES} ++ ${LIBSYSTEMD_LIBRARIES} ++ OpenSSL::Crypto ++ -lukuiinputgatherclient ++ ${GIOUNIX2_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_screenlock ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_screenlock/main.cpp b/tests/unit_test_screenlock/main.cpp +new file mode 100644 +index 0000000..9250f9b +--- /dev/null ++++ b/tests/unit_test_screenlock/main.cpp +@@ -0,0 +1,8 @@ ++#include <gtest/gtest.h> ++ ++int main(int argc, char **argv) ++{ ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} +diff --git a/tests/unit_test_screenlock/unit_test_screenlock.cpp b/tests/unit_test_screenlock/unit_test_screenlock.cpp +new file mode 100644 +index 0000000..bdbe630 +--- /dev/null ++++ b/tests/unit_test_screenlock/unit_test_screenlock.cpp +@@ -0,0 +1,96 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 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 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 <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include "../../src/ukccplugins/sessiondbus/screenlockinterface.h" ++#include <qgsettings.h> ++ ++class ScreenlockInterfaceTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pDbusUpperInterfaceDbus = new DbusUpperInterface(); ++ m_pScreenlockInterface = new ScreenlockInterface(m_pDbusUpperInterfaceDbus, m_pDbusUpperInterfaceDbus); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ if (m_pScreenlockInterface) { ++ delete m_pScreenlockInterface; ++ m_pScreenlockInterface = nullptr; ++ } ++ delete m_pDbusUpperInterfaceDbus; ++ m_pDbusUpperInterfaceDbus = nullptr; ++ } ++ ++ static ScreenlockInterface *m_pScreenlockInterface; ++ static DbusUpperInterface *m_pDbusUpperInterfaceDbus; ++}; ++ ++DbusUpperInterface *ScreenlockInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr; ++ScreenlockInterface *ScreenlockInterfaceTest::m_pScreenlockInterface = nullptr; ++ ++TEST_F(ScreenlockInterfaceTest, setShowOnLogin) ++{ ++ bool oldValue = m_pScreenlockInterface->property("showOnLogin").toBool(); ++ m_pScreenlockInterface->setShowOnLogin(false); ++ bool newValue = m_pScreenlockInterface->property("showOnLogin").toBool(); ++ ASSERT_EQ(newValue, false); ++ m_pScreenlockInterface->setShowOnLogin(oldValue); ++} ++ ++TEST_F(ScreenlockInterfaceTest, setWallpaper) ++{ ++ QGSettings gset("org.ukui.screensaver"); ++ std::string oldValue = gset.get("background").toString().toStdString(); ++ m_pScreenlockInterface->setWallpaper("/usr/share/backgrounds/city.jpg"); ++ std::string newValue = gset.get("background").toString().toStdString(); ++ ASSERT_STREQ(newValue.c_str(), "/usr/share/backgrounds/city.jpg"); ++ m_pScreenlockInterface->setWallpaper(oldValue.c_str()); ++} ++ ++TEST_F(ScreenlockInterfaceTest, resetDefault) ++{ ++ QGSettings gset("org.ukui.screensaver"); ++ std::string oldValue = gset.get("background").toString().toStdString(); ++ m_pScreenlockInterface->resetDefault(); ++ std::string newValue = gset.get("background").toString().toStdString(); ++ ASSERT_STREQ(newValue.c_str(), "/usr/share/backgrounds/1-openkylin.jpg"); ++ m_pScreenlockInterface->setWallpaper(oldValue.c_str()); ++} ++ ++TEST_F(ScreenlockInterfaceTest, getPreviewWallpapers) ++{ ++ int size = m_pScreenlockInterface->getPreviewWallpapers().size(); ++ ASSERT_GE(size, 0); ++} ++ ++TEST_F(ScreenlockInterfaceTest, getSourceWallpapers) ++{ ++ int size = m_pScreenlockInterface->getSourceWallpapers().size(); ++ ASSERT_GE(size, 0); ++} ++ ++TEST_F(ScreenlockInterfaceTest, getWallpaper) ++{ ++ int size = m_pScreenlockInterface->getWallpaper().size(); ++ ASSERT_GE(size, 0); ++} +diff --git a/tests/unit_test_screensaver/CMakeLists.txt b/tests/unit_test_screensaver/CMakeLists.txt +new file mode 100644 +index 0000000..aced7aa +--- /dev/null ++++ b/tests/unit_test_screensaver/CMakeLists.txt +@@ -0,0 +1,149 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core DBus Network Test REQUIRED) ++find_package(OpenSSL REQUIRED) ++find_package(PkgConfig REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3) ++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) ++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量 ++find_library(PAM_LIBRARIES pam) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/authpamthread.cpp ++ ../../src/lock-backend/pamauthenticate.cpp ++ ../../src/lock-backend/lightdmhelper.cpp ++ ../../src/lock-backend/dbusupperinterface.cpp ++ ../../src/lock-backend/gsettingshelper.cpp ++ ../../src/lock-backend/bioauthenticate.cpp ++ ../../src/lock-backend/switchuserutils.cpp ++ ../../src/dbusifs/accountshelper.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/common/configuration.cpp ++ ../../src/common/rsac.cpp ++ ../../src/dbusifs/giodbus.cpp ++ ../../src/dbusifs/uniauthservice.cpp ++ ../../src/lock-backend/securityuser.cpp ++ ../../src/dbusifs/freedesktophelper.cpp ++ ../../src/dbusifs/login1helper.cpp ++ ../../src/dbusifs/usdhelper.cpp ++ ../../src/dbusifs/upowerhelper.cpp ++ ../../src/dbusifs/sessionhelper.cpp ++ ../../src/dbusifs/dbusservermanager.cpp ++ ../../src/dbusifs/systemupgradehelper.cpp ++ ../../src/lock-backend/sessionwatcher.cpp ++ ../../src/dbusifs/kglobalaccelhelper.cpp ++ ../../src/dbusifs/libinputswitchevent.cpp ++ ../../src/lock-backend/personalizeddata.cpp ++ ../../src/dbusifs/biometrichelper.cpp ++ ../../src/dbusifs/device.cpp ++ ../../src/dbusifs/machinemodel.cpp ++ ../../src/dbusifs/enginedevice.cpp ++ ../../src/common/biodefines.cpp ++ ../../src/QtSingleApplication/qtlocalpeer.cpp ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp ++ ../../src/ukccplugins/sessiondbus/screensaverinterface.cpp ++ unit_test_screensaver.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/authpamthread.h ++ ../../src/lock-backend/pamauthenticate.h ++ ../../src/lock-backend/lightdmhelper.h ++ ../../src/lock-backend/dbusupperinterface.h ++ ../../src/lock-backend/gsettingshelper.h ++ ../../src/lock-backend/bioauthenticate.h ++ ../../src/lock-backend/switchuserutils.h ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/common/configuration.h ++ ../../src/common/rsac.h ++ ../../src/dbusifs/giodbus.h ++ ../../src/dbusifs/accountshelper.h ++ ../../src/common/configuration.h ++ ../../src/dbusifs/uniauthservice.h ++ ../../src/lock-backend/securityuser.h ++ ../../src/dbusifs/freedesktophelper.h ++ ../../src/dbusifs/login1helper.h ++ ../../src/dbusifs/usdhelper.h ++ ../../src/dbusifs/upowerhelper.h ++ ../../src/dbusifs/dbusservermanager.h ++ ../../src/dbusifs/sessionhelper.h ++ ../../src/dbusifs/systemupgradehelper.h ++ ../../src/lock-backend/sessionwatcher.h ++ ../../src/dbusifs/kglobalaccelhelper.h ++ ../../src/dbusifs/libinputswitchevent.h ++ ../../src/lock-backend/personalizeddata.h ++ ../../src/dbusifs/biometrichelper.h ++ ../../src/dbusifs/device.h ++ ../../src/dbusifs/enginedevice.h ++ ../../src/dbusifs/machinemodel.h ++ ../../src/common/biodefines.h ++ ../kt-test-utils/cpp-stub-ext/stubext.h ++ ../kt-test-utils/cpp-stub-ext/stub-shadow.h ++ ../../src/QtSingleApplication/qtlocalpeer.h ++ ../../src/ukccplugins/sessiondbus/screensaverinterface.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${Qt5Test_INCLUDE_DIRS} ++ ${LIGHTDM-QT5-3_INCLUDE_DIRS} ++ ${LIBSYSTEMD_INCLUDE_DIRS} ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/ ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_screensaver ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_screensaver ++ Qt5::Core ++ Qt5::DBus ++ Qt5::Test ++ Qt5::Network ++ ${QGS_LIBRARIES} ++ ${PAM_LIBRARIES} ++ ${LIGHTDM-QT5-3_LIBRARIES} ++ ${LIBSYSTEMD_LIBRARIES} ++ OpenSSL::Crypto ++ -lukuiinputgatherclient ++ ${GIOUNIX2_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_screensaver ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_screensaver/main.cpp b/tests/unit_test_screensaver/main.cpp +new file mode 100644 +index 0000000..9250f9b +--- /dev/null ++++ b/tests/unit_test_screensaver/main.cpp +@@ -0,0 +1,8 @@ ++#include <gtest/gtest.h> ++ ++int main(int argc, char **argv) ++{ ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} +diff --git a/tests/unit_test_screensaver/unit_test_screensaver.cpp b/tests/unit_test_screensaver/unit_test_screensaver.cpp +new file mode 100644 +index 0000000..2c27798 +--- /dev/null ++++ b/tests/unit_test_screensaver/unit_test_screensaver.cpp +@@ -0,0 +1,141 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 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 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 <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include "../../src/ukccplugins/sessiondbus/screensaverinterface.h" ++#include <qgsettings.h> ++ ++class ScreensaverInterfaceTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pDbusUpperInterfaceDbus = new DbusUpperInterface(); ++ m_pScreenSaverInterface = new ScreensaverInterface(m_pDbusUpperInterfaceDbus, m_pDbusUpperInterfaceDbus); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ if (m_pScreenSaverInterface) { ++ delete m_pScreenSaverInterface; ++ m_pScreenSaverInterface = nullptr; ++ } ++ delete m_pDbusUpperInterfaceDbus; ++ m_pDbusUpperInterfaceDbus = nullptr; ++ } ++ ++ static ScreensaverInterface *m_pScreenSaverInterface; ++ static DbusUpperInterface *m_pDbusUpperInterfaceDbus; ++}; ++ ++DbusUpperInterface *ScreensaverInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr; ++ScreensaverInterface *ScreensaverInterfaceTest::m_pScreenSaverInterface = nullptr; ++ ++TEST_F(ScreensaverInterfaceTest, setPreentryTime) ++{ ++ int oldValue = m_pScreenSaverInterface->property("preentryTime").toInt(); ++ m_pScreenSaverInterface->setPreentryTime(10); ++ int newValue = m_pScreenSaverInterface->property("preentryTime").toInt(); ++ ASSERT_EQ(newValue, 10); ++ m_pScreenSaverInterface->setPreentryTime(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setScreensaverType) ++{ ++ QGSettings gsetting("org.ukui.screensaver"); ++ std::string oldValue = m_pScreenSaverInterface->property("screensaverType").toString().toStdString(); ++ m_pScreenSaverInterface->setScreensaverType("ukui"); ++ std::string newValue = gsetting.get("mode").toString().toStdString(); ++ ++ ASSERT_STREQ(newValue.c_str(), "default-ukui"); ++ m_pScreenSaverInterface->setScreensaverType(oldValue.c_str()); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setShowBreakTimeUkuiCustom) ++{ ++ bool oldValue = m_pScreenSaverInterface->property("showBreakTimeCustom").toBool(); ++ m_pScreenSaverInterface->setShowBreakTimeCustom(true); ++ bool newValue = m_pScreenSaverInterface->property("showBreakTimeCustom").toBool(); ++ ASSERT_EQ(newValue, true); ++ m_pScreenSaverInterface->setShowBreakTimeCustom(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setShowBreakTimeUkui) ++{ ++ bool oldValue = m_pScreenSaverInterface->property("showBreakTimeUkui").toBool(); ++ m_pScreenSaverInterface->setShowBreakTimeUkui(false); ++ bool newValue = m_pScreenSaverInterface->property("showBreakTimeUkui").toBool(); ++ ASSERT_EQ(newValue, false); ++ m_pScreenSaverInterface->setShowBreakTimeUkui(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setScreenLockEnabled) ++{ ++ bool oldValue = m_pScreenSaverInterface->property("screenLockEnabled").toBool(); ++ m_pScreenSaverInterface->setScreenLockEnabled(false); ++ bool newValue = m_pScreenSaverInterface->property("screenLockEnabled").toBool(); ++ ASSERT_EQ(newValue, false); ++ m_pScreenSaverInterface->setScreenLockEnabled(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setCustomPath) ++{ ++ std::string oldValue = m_pScreenSaverInterface->property("customPath").toString().toStdString(); ++ m_pScreenSaverInterface->setCustomPath("/test/path"); ++ std::string newValue = m_pScreenSaverInterface->property("customPath").toString().toStdString(); ++ ASSERT_STREQ(newValue.c_str(), "/test/path"); ++ m_pScreenSaverInterface->setCustomPath(oldValue.c_str()); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setSwitchRandom) ++{ ++ bool oldValue = m_pScreenSaverInterface->property("switchRandom").toBool(); ++ m_pScreenSaverInterface->setSwitchRandom(false); ++ bool newValue = m_pScreenSaverInterface->property("switchRandom").toBool(); ++ ASSERT_EQ(newValue, false); ++ m_pScreenSaverInterface->setSwitchRandom(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setCycleTime) ++{ ++ int oldValue = m_pScreenSaverInterface->property("cycleTime").toInt(); ++ m_pScreenSaverInterface->setCycleTime(60); ++ int newValue = m_pScreenSaverInterface->property("cycleTime").toInt(); ++ ASSERT_EQ(newValue, 60); ++ m_pScreenSaverInterface->setCycleTime(oldValue); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setCustomText) ++{ ++ std::string oldValue = m_pScreenSaverInterface->property("customText").toString().toStdString(); ++ m_pScreenSaverInterface->setCustomText("test custom text"); ++ std::string newValue = m_pScreenSaverInterface->property("customText").toString().toStdString(); ++ ASSERT_STREQ(newValue.c_str(), "test custom text"); ++ m_pScreenSaverInterface->setCustomText(oldValue.c_str()); ++} ++ ++TEST_F(ScreensaverInterfaceTest, setCustomTextCentered) ++{ ++ bool oldValue = m_pScreenSaverInterface->property("customTextCentered").toBool(); ++ m_pScreenSaverInterface->setCustomTextCentered(false); ++ bool newValue = m_pScreenSaverInterface->property("customTextCentered").toBool(); ++ ASSERT_EQ(newValue, false); ++ m_pScreenSaverInterface->setCustomTextCentered(oldValue); ++} +diff --git a/tests/unit_test_session_helper/CMakeLists.txt b/tests/unit_test_session_helper/CMakeLists.txt +new file mode 100644 +index 0000000..48b6590 +--- /dev/null ++++ b/tests/unit_test_session_helper/CMakeLists.txt +@@ -0,0 +1,74 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control -fno-exceptions") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/sessionhelper.cpp ++ ../../src/dbusifs/login1helper.cpp ++ ../../src/dbusifs/dbusservermanager.cpp ++ ../../src/userinfo.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/lock-backend/gsettingshelper.cpp ++ unit_test_session_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/userinfo.h ++ ../../src/common/global_utils.h ++ ../../src/dbusifs/sessionhelper.h ++ ../../src/dbusifs/login1helper.h ++ ../../src/dbusifs/dbusservermanager.h ++ ../../src/lock-backend/gsettingshelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_session_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_session_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ ${QGS_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_session_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_session_helper/main.cpp b/tests/unit_test_session_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_session_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_session_helper/unit_test_session_helper.cpp b/tests/unit_test_session_helper/unit_test_session_helper.cpp +new file mode 100644 +index 0000000..0abfdc5 +--- /dev/null ++++ b/tests/unit_test_session_helper/unit_test_session_helper.cpp +@@ -0,0 +1,70 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/sessionhelper.h" ++#include "../../src/dbusifs/login1helper.h" ++ ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class SessionHelperTest : public testing::Test, public QObject ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_login1Helper = QSharedPointer<Login1Helper>(new Login1Helper(nullptr)); ++ m_pSessionHelperDbus = new SessionHelper(m_login1Helper); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pSessionHelperDbus; ++ m_pSessionHelperDbus = nullptr; ++ } ++ ++ static SessionHelper *m_pSessionHelperDbus; ++ static QSharedPointer<Login1Helper> m_login1Helper; ++}; ++ ++SessionHelper *SessionHelperTest::m_pSessionHelperDbus = nullptr; ++QSharedPointer<Login1Helper> SessionHelperTest::m_login1Helper = nullptr; ++ ++TEST_F(SessionHelperTest, canAction) ++{ ++ bool value = m_pSessionHelperDbus->canAction(PowerHibernate); ++ bool value1 = m_pSessionHelperDbus->canAction(PowerSuspend); ++ bool value2 = m_pSessionHelperDbus->canAction(PowerMonitorOff); ++ bool value3 = m_pSessionHelperDbus->canAction(PowerLogout); ++ bool value4 = m_pSessionHelperDbus->canAction(PowerReboot); ++ bool value5 = m_pSessionHelperDbus->canAction(PowerShutdown); ++ bool value6 = m_pSessionHelperDbus->canAction(PowerSwitchUser); ++ // bool value7 = m_pSessionHelperDbus->canAction(TestAction); ++ ASSERT_EQ(value, true); ++ ASSERT_EQ(value1, true); ++ ASSERT_EQ(value2, true); ++ ASSERT_EQ(value3, true); ++ ASSERT_EQ(value4, true); ++ ASSERT_EQ(value5, true); ++ ASSERT_EQ(value6, true); ++} ++ ++TEST_F(SessionHelperTest, doAction) ++{ ++ bool value = m_pSessionHelperDbus->doAction("Suspend"); ++ ASSERT_EQ(value, true); ++} ++ ++TEST_F(SessionHelperTest, getLockCheckStatus) ++{ ++ QStringList value = m_pSessionHelperDbus->getLockCheckStatus("shutdown"); ++ ASSERT_EQ(value.isEmpty(), true); ++} ++ ++TEST_F(SessionHelperTest, playShutdownMusic) ++{ ++ bool value = m_pSessionHelperDbus->playShutdownMusic("Logout"); ++ m_pSessionHelperDbus->playShutdownMusic("Reboot"); ++ m_pSessionHelperDbus->playShutdownMusic("SwitchUser"); ++ ASSERT_EQ(value, true); ++} +diff --git a/tests/unit_test_session_watcher/CMakeLists.txt b/tests/unit_test_session_watcher/CMakeLists.txt +new file mode 100644 +index 0000000..4c5ad7d +--- /dev/null ++++ b/tests/unit_test_session_watcher/CMakeLists.txt +@@ -0,0 +1,77 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus X11Extras REQUIRED) ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(QGS REQUIRED gsettings-qt) ++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++find_package(X11 REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/sessionwatcher.cpp ++ ../../src/common/utils.cpp ++ ../../src/common/global_utils.cpp ++ ../../src/lock-backend/gsettingshelper.cpp ++ unit_test_session_watcher.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/common/utils.h ++ ../../src/common/global_utils.h ++ ../../src/lock-backend/sessionwatcher.h ++ ../../src/lock-backend/gsettingshelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${QGS_INCLUDE_DIRS} ++ ${GIOUNIX2_INCLUDE_DIRS} ++ ${X11_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_session_watcher ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_session_watcher ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ Qt5::X11Extras ++ ${QGS_LIBRARIES} ++ ${GIOUNIX2_LIBRARIES} ++ ${X11_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_session_watcher ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_session_watcher/main.cpp b/tests/unit_test_session_watcher/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_session_watcher/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_session_watcher/unit_test_session_watcher.cpp b/tests/unit_test_session_watcher/unit_test_session_watcher.cpp +new file mode 100644 +index 0000000..1b12ca6 +--- /dev/null ++++ b/tests/unit_test_session_watcher/unit_test_session_watcher.cpp +@@ -0,0 +1,35 @@ ++#include <gtest/gtest.h> ++ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include "../../src/lock-backend/sessionwatcher.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class SessionWatcherTest : public testing::Test ++{ ++protected: ++ QSharedPointer<GSettingsHelper> m_pGSettingsHelperDbus; ++ QSharedPointer<SessionWatcher> m_pSessionWatcherDbus; ++ ++ void SetUp() override ++ { ++ m_pGSettingsHelperDbus = QSharedPointer<GSettingsHelper>(new GSettingsHelper()); ++ m_pSessionWatcherDbus = QSharedPointer<SessionWatcher>(new SessionWatcher(m_pGSettingsHelperDbus)); ++ } ++ ++ void TearDown() override ++ { ++ m_pSessionWatcherDbus.reset(); ++ m_pGSettingsHelperDbus.reset(); ++ } ++}; ++ ++TEST_F(SessionWatcherTest, GetCurUserName) ++{ ++ m_pSessionWatcherDbus->onStatusChanged(0); ++ m_pSessionWatcherDbus->onStatusChanged(1); ++ m_pSessionWatcherDbus->onStatusChanged(2); ++ m_pSessionWatcherDbus->onStatusChanged(3); ++} +diff --git a/tests/unit_test_switch_user/CMakeLists.txt b/tests/unit_test_switch_user/CMakeLists.txt +new file mode 100644 +index 0000000..65e67e4 +--- /dev/null ++++ b/tests/unit_test_switch_user/CMakeLists.txt +@@ -0,0 +1,67 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++find_package(PkgConfig REQUIRED) ++ ++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) ++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/lock-backend/switchuserutils.cpp ++ ../../src/common/global_utils.cpp ++ unit_test_switch_user.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/lock-backend/switchuserutils.h ++ ../../src/common/global_utils.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++ ${GLIB2_INCLUDE_DIRS} ++ ${LIBSYSTEMD_INCLUDE_DIRS} ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_switch_user ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_switch_user ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++ ${LIBSYSTEMD_LIBRARIES} ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_switch_user ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++ ${GLIB2_LIBRARIES} ++) ++ +diff --git a/tests/unit_test_switch_user/main.cpp b/tests/unit_test_switch_user/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_switch_user/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_switch_user/unit_test_switch_user.cpp b/tests/unit_test_switch_user/unit_test_switch_user.cpp +new file mode 100644 +index 0000000..3a677fd +--- /dev/null ++++ b/tests/unit_test_switch_user/unit_test_switch_user.cpp +@@ -0,0 +1,71 @@ ++#include <gtest/gtest.h> ++ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include "../../src/common/global_utils.h" ++#include "../../src/lock-backend/switchuserutils.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class SwitchUserUtilsTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pSwitchUserUtilsDbus = new SwitchUserUtils(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pSwitchUserUtilsDbus; ++ m_pSwitchUserUtilsDbus = nullptr; ++ } ++ ++ static SwitchUserUtils *m_pSwitchUserUtilsDbus; ++}; ++ ++SwitchUserUtils *SwitchUserUtilsTest::m_pSwitchUserUtilsDbus = nullptr; ++ ++ ++// 测试 GetCurUserName 函数 ++TEST_F(SwitchUserUtilsTest, GetCurUserName) { ++ QString userName = m_pSwitchUserUtilsDbus->GetCurUserName(); ++ EXPECT_EQ(userName, "testuser"); ++} ++ ++ ++// 测试 GetUidByName 函数 ++TEST_F(SwitchUserUtilsTest, GetUidByName) { ++ int uid = m_pSwitchUserUtilsDbus->GetUidByName(getenv("USER")); ++ EXPECT_EQ(uid, 1000); ++} ++ ++ ++// 测试 GetUserUDII 函数 ++TEST_F(SwitchUserUtilsTest, GetUserUDII) { ++ UserDisplayIfInfo userDisplayIfInfo = m_pSwitchUserUtilsDbus->GetUserUDII(getenv("USER")); ++ ++ ++ EXPECT_EQ(userDisplayIfInfo.strSeatPath, "/org/freedesktop/DisplayManager/Seat1"); ++ EXPECT_EQ(userDisplayIfInfo.strUserName, "testuser"); ++ EXPECT_EQ(userDisplayIfInfo.strSessionPath, "/org/freedesktop/DisplayManager/Session1"); ++} ++ ++ ++// 测试 SwitchToUserSession 函数 ++TEST_F(SwitchUserUtilsTest, SwitchToUserSession) { ++ UserDisplayIfInfo userDisplayIfInfo; ++ userDisplayIfInfo.strSeatPath = "/org/freedesktop/DisplayManager/Seat1"; ++ userDisplayIfInfo.strUserName = "testuser"; ++ userDisplayIfInfo.strSessionPath = "/org/freedesktop/DisplayManager/Session1"; ++ int result = m_pSwitchUserUtilsDbus->SwitchToUserSession("/org/freedesktop/DisplayManager/Seat1", userDisplayIfInfo); ++ EXPECT_EQ(result, 0); ++} ++ ++ ++// 测试 SwitchToUserLock 函数 ++TEST_F(SwitchUserUtilsTest, SwitchToUserLock) { ++ bool result = m_pSwitchUserUtilsDbus->SwitchToUserLock(); ++ EXPECT_TRUE(result); ++} +diff --git a/tests/unit_test_systemupgrade_helper/CMakeLists.txt b/tests/unit_test_systemupgrade_helper/CMakeLists.txt +new file mode 100644 +index 0000000..7171972 +--- /dev/null ++++ b/tests/unit_test_systemupgrade_helper/CMakeLists.txt +@@ -0,0 +1,59 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/systemupgradehelper.cpp ++ unit_test_systemupgrade_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/dbusifs/systemupgradehelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_systemupgrade_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_systemupgrade_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_systemupgrade_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_systemupgrade_helper/main.cpp b/tests/unit_test_systemupgrade_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_systemupgrade_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp b/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp +new file mode 100644 +index 0000000..b839471 +--- /dev/null ++++ b/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp +@@ -0,0 +1,45 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/systemupgradehelper.h" ++ ++#include "stubext.h" ++ ++using namespace stub_ext; ++ ++class SystemUpgradeHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pSystemUpgradeHelperDbus = new SystemUpgradeHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pSystemUpgradeHelperDbus; ++ m_pSystemUpgradeHelperDbus = nullptr; ++ } ++ ++ static SystemUpgradeHelper *m_pSystemUpgradeHelperDbus; ++}; ++ ++SystemUpgradeHelper *SystemUpgradeHelperTest::m_pSystemUpgradeHelperDbus = nullptr; ++ ++TEST_F(SystemUpgradeHelperTest, checkSystemUpgrade) ++{ ++ bool value = m_pSystemUpgradeHelperDbus->checkSystemUpgrade(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(SystemUpgradeHelperTest, doUpgradeThenRboot) ++{ ++ bool value = m_pSystemUpgradeHelperDbus->doUpgradeThenRboot(); ++ ASSERT_EQ(value, false); ++} ++ ++TEST_F(SystemUpgradeHelperTest, doUpgradeThenShutdown) ++{ ++ bool value = m_pSystemUpgradeHelperDbus->doUpgradeThenShutdown(); ++ ASSERT_EQ(value, false); ++} +diff --git a/tests/unit_test_uniauth_service/CMakeLists.txt b/tests/unit_test_uniauth_service/CMakeLists.txt +new file mode 100644 +index 0000000..b71fffa +--- /dev/null ++++ b/tests/unit_test_uniauth_service/CMakeLists.txt +@@ -0,0 +1,62 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") ++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/uniauthservice.cpp ++ ../../src/dbusifs/freedesktophelper.cpp ++ unit_test_uniauth_service.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/common/definetypes.h ++ ../../src/dbusifs/uniauthservice.h ++ ../../src/dbusifs/freedesktophelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_uniauth_service ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_uniauth_service ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_uniauth_service ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_uniauth_service/main.cpp b/tests/unit_test_uniauth_service/main.cpp +new file mode 100644 +index 0000000..314ea99 +--- /dev/null ++++ b/tests/unit_test_uniauth_service/main.cpp +@@ -0,0 +1,11 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} +diff --git a/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp b/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp +new file mode 100644 +index 0000000..104af35 +--- /dev/null ++++ b/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp +@@ -0,0 +1,159 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/uniauthservice.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class UniAuthServiceTest : public testing::Test ++{ ++//protected: ++// static void SetUpTestSuite() ++// { ++// m_pUniAuthServiceDbus = new UniAuthService(); ++// } ++ ++// static void TearDownTestSuite() ++// { ++// delete m_pUniAuthServiceDbus; ++// m_pUniAuthServiceDbus = nullptr; ++// } ++ ++// static UniAuthService *m_pUniAuthServiceDbus; ++}; ++ ++//UniAuthService *UniAuthServiceTest::m_pUniAuthServiceDbus = nullptr; ++ ++TEST_F(UniAuthServiceTest, DefaultDevice) ++{ ++ if (UniAuthService::instance()) { ++ QString oldValue = UniAuthService::instance()->getDefaultDevice(getenv("USER"), 0); ++ UniAuthService::instance()->setDefaultDevice(0, "testValue"); ++ QString newValue = UniAuthService::instance()->getDefaultDevice(getenv("USER"), 0); ++ std::string str = newValue.toStdString(); ++ const char* cstr = str.data(); ++ ASSERT_STREQ(cstr, "testValue"); ++ UniAuthService::instance()->setDefaultDevice(0, oldValue); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, BioAuthStatus) ++{ ++ if (UniAuthService::instance()) { ++ bool oldValue = UniAuthService::instance()->getBioAuthStatus(getenv("USER"), 0); ++ UniAuthService::instance()->setBioAuthStatus(0, !oldValue); ++ bool newValue = UniAuthService::instance()->getBioAuthStatus(getenv("USER"), 0); ++ ASSERT_EQ(newValue, !oldValue); ++ UniAuthService::instance()->setBioAuthStatus(0, oldValue); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, AllDefaultDevice) ++{ ++ if (UniAuthService::instance()) { ++ QStringList defaultDeviceList = UniAuthService::instance()->getAllDefaultDevice(getenv("USER")); ++ ASSERT_EQ(defaultDeviceList.isEmpty(), false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, MaxFailedTimes) ++{ ++ if (UniAuthService::instance()) { ++ int maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes(); ++ ASSERT_EQ(maxFailedTimes, 5); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, QRCodeEnable) ++{ ++ if (UniAuthService::instance()) { ++ bool qRCodeEnable = UniAuthService::instance()->getQRCodeEnable(); ++ ASSERT_EQ(qRCodeEnable, true); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, DoubleAuth) ++{ ++ if (UniAuthService::instance()) { ++ bool doubleAuth = UniAuthService::instance()->getDoubleAuth(); ++ ASSERT_EQ(doubleAuth, false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, UserBind) ++{ ++ if (UniAuthService::instance()) { ++ bool userBind = UniAuthService::instance()->getUserBind(); ++ ASSERT_EQ(userBind, false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, IsShownInControlCenter) ++{ ++ if (UniAuthService::instance()) { ++ bool isShownInControlCenter = UniAuthService::instance()->getIsShownInControlCenter(); ++ ASSERT_EQ(isShownInControlCenter, false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, HiddenSwitchButton) ++{ ++ if (UniAuthService::instance()) { ++ bool hiddenSwitchButton = UniAuthService::instance()->getHiddenSwitchButton(); ++ ASSERT_EQ(hiddenSwitchButton, false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, getFTimeoutTimes) ++{ ++ if (UniAuthService::instance()) { ++ int hiddenSwitchButton = UniAuthService::instance()->getFTimeoutTimes(); ++ ASSERT_EQ(hiddenSwitchButton, 5); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, isActivatable) ++{ ++ if (UniAuthService::instance()) { ++ bool hiddenSwitchButton = UniAuthService::instance()->isActivatable(); ++ ASSERT_EQ(hiddenSwitchButton, true); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, isUserNameValid) ++{ ++ if (UniAuthService::instance()) { ++ bool hiddenSwitchButton = UniAuthService::instance()->isUserNameValid(getenv("USER")); ++ ASSERT_EQ(hiddenSwitchButton, true); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, GetLastLoginUser) ++{ ++ if (UniAuthService::instance()) { ++ QString hiddenSwitchButton = UniAuthService::instance()->GetLastLoginUser(); ++ ASSERT_EQ(hiddenSwitchButton.isEmpty(), false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, GetQuickLoginUser) ++{ ++ if (UniAuthService::instance()) { ++ QString hiddenSwitchButton = UniAuthService::instance()->GetQuickLoginUser(); ++ ASSERT_EQ(hiddenSwitchButton.isEmpty(), false); ++ } ++} ++ ++TEST_F(UniAuthServiceTest, getUseFirstDevice) ++{ ++ if (UniAuthService::instance()) { ++ bool value = UniAuthService::instance()->getUseFirstDevice(); ++ UniAuthService::instance()->SwitchToUser(getenv("USER")); ++ UniAuthService::instance()->SwitchToGreeterUser(getenv("USER")); ++ UniAuthService::instance()->getWillSwitchUser(); ++ UniAuthService::instance()->SaveLastLoginUser(UniAuthService::instance()->GetLastLoginUser()); ++ UniAuthService::instance()->SaveQuickLoginUser(UniAuthService::instance()->GetQuickLoginUser()); ++ ASSERT_EQ(value, false); ++ } ++} +diff --git a/tests/unit_test_usd_helper/CMakeLists.txt b/tests/unit_test_usd_helper/CMakeLists.txt +new file mode 100644 +index 0000000..fbf768a +--- /dev/null ++++ b/tests/unit_test_usd_helper/CMakeLists.txt +@@ -0,0 +1,57 @@ ++# CMake 最低版本要求 ++cmake_minimum_required(VERSION 3.10) ++ ++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED) ++ ++# 包含 GTest 库和 pthread 库 ++find_package(GTest REQUIRED) ++find_package(Threads REQUIRED) ++ ++# 设置 C++ 标准 ++set(CMAKE_CXX_STANDARD 17) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ ++ ++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置) ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control") ++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") ++ ++# 定义源文件列表,对应原来的SOURCES变量 ++set(SOURCES ++ ../../src/dbusifs/usdhelper.cpp ++ unit_test_usd_helper.cpp ++ main.cpp ++) ++ ++# 定义头文件列表,对应原来的HEADERS变量 ++set(HEADERS ++ ../../src/dbusifs/usdhelper.h ++) ++ ++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量 ++include_directories( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub ++ ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext ++) ++ ++# 使用qt5_wrap_cpp生成元对象代码相关的源文件 ++qt5_wrap_cpp(MOC_SOURCES ${HEADERS}) ++ ++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去 ++add_executable(unit_test_usd_helper ${SOURCES} ${MOC_SOURCES}) ++ ++# 链接Qt相关的库 ++target_link_libraries(unit_test_usd_helper ++ Qt5::Core ++ Qt5::Gui ++ Qt5::DBus ++) ++ ++# 链接 GTest 库 ++target_link_libraries(unit_test_usd_helper ++ GTest::GTest ++ GTest::Main ++ Threads::Threads ++) ++ +diff --git a/tests/unit_test_usd_helper/main.cpp b/tests/unit_test_usd_helper/main.cpp +new file mode 100644 +index 0000000..37b3fbf +--- /dev/null ++++ b/tests/unit_test_usd_helper/main.cpp +@@ -0,0 +1,12 @@ ++#include <gtest/gtest.h> ++#include <QGuiApplication> ++ ++ ++int main(int argc, char **argv) ++{ ++ QGuiApplication a(argc, argv); ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/unit_test_usd_helper/unit_test_usd_helper.cpp b/tests/unit_test_usd_helper/unit_test_usd_helper.cpp +new file mode 100644 +index 0000000..f9c90a0 +--- /dev/null ++++ b/tests/unit_test_usd_helper/unit_test_usd_helper.cpp +@@ -0,0 +1,32 @@ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../../src/dbusifs/usdhelper.h" ++ ++#include "stubext.h" ++using namespace stub_ext; ++ ++class UsdHelperTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pUsdHelperDbus = new UsdHelper(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pUsdHelperDbus; ++ m_pUsdHelperDbus = nullptr; ++ } ++ ++ static UsdHelper *m_pUsdHelperDbus; ++}; ++ ++UsdHelper *UsdHelperTest::m_pUsdHelperDbus = nullptr; ++ ++TEST_F(UsdHelperTest, usdExternalDoAction) ++{ ++ bool value = m_pUsdHelperDbus->usdExternalDoAction(-1); ++ ASSERT_EQ(value, false); ++} +diff --git a/ukccplugins_i18n_ts/CMakeLists.txt b/ukccplugins_i18n_ts/CMakeLists.txt +new file mode 100644 +index 0000000..4eecf02 +--- /dev/null ++++ b/ukccplugins_i18n_ts/CMakeLists.txt +@@ -0,0 +1,12 @@ ++find_package(Qt5LinguistTools) ++ ++file(GLOB ts_files *.ts) ++qt5_add_translation(qm_files ${ts_files}) ++ ++add_custom_target(ukccplugins_i18n ++ DEPENDS ${qm_files} ++ SOURCES ${ts_files} ++ ) ++ ++install(FILES ${ts_files} DESTINATION /usr/share/ukui-screensaver/ukccplugins/i18n/) ++install(FILES ${qm_files} DESTINATION /usr/share/ukui-screensaver/ukccplugins/i18n_qm/) +diff --git a/ukccplugins_i18n_ts/bo.ts b/ukccplugins_i18n_ts/bo.ts +new file mode 100644 +index 0000000..b9e3413 +--- /dev/null ++++ b/ukccplugins_i18n_ts/bo.ts +@@ -0,0 +1,314 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/bo_CN.ts b/ukccplugins_i18n_ts/bo_CN.ts +new file mode 100644 +index 0000000..8056d74 +--- /dev/null ++++ b/ukccplugins_i18n_ts/bo_CN.ts +@@ -0,0 +1,493 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="bo_CN"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>བརྙན་ཤེལ་གྱི་སྒོ་བརྒྱབ་པ</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་འབྲེལ་མཐུད།</translation> ++ <extra-contents_path>/Screenlock/Screenlock Interface</extra-contents_path> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">ཟྭ་ངོས་སུ་ཆ་འཕྲིན་མངོན་པར་བྱས་ཡོད།</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">བརྙན་ཤེལ་སྟེང་གི་བརྙན་ཤེལ་གྱི་པར་རིས་འགྲེམས་སྟོན་བྱས།</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">འབྲེལ་ལྡན་སྒྲིག་འགོད་</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">སྒོ་རྒྱག་འཆར་ཆས་</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">ཉི་ནུབ</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation> ++ <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་དུས་ཚོད་འགོར་འགྱངས</translation> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">དྲ་ཐོག་པར་རིས།</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1min</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5min</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10min</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30min</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45min</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1hour</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2hour</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3hour</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">གཏན་ནས་བྱེད་མི་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *wdp)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་གྱང་ཤོག་ཡིག་ཆ་བདམས་པ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>བདམས་ཐོན་བྱུང་བ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>གོ་གནས་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>ཡིག་ཆའི་མིང་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>ཕྱིར་འཐེན།</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>བརྙན་ཤེལ་སྟེང་གི་བརྙན་ཤེལ་གྱི་པར་རིས་འགྲེམས་སྟོན་བྱས།</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>ཟྭ་དང་བྲལ་ནས་(ལག་ཁྱེར་ཁ་པར་མེད་པར་གྱུར་རྗེས་མ་ལག་ལ་སྒོ་བརྒྱབ་ནས་གཏན་ཁེལ་བྱེད་ངེས་ )</translation> ++ <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>སྒྲིག་ཆས་དམིགས་འཛུགས་བྱ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>ལག་ཁྱེར་ཁ་པར་ཆ་འགྲིག་མེད། "སོ་སྔོན་པོ་"རུ་བསྒྱུར་ནས་སྡེབ་སྒྲིག་བྱེད་རོགས།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>བརྙན་ཤེལ་གྱི་སྒོ་བརྒྱབ་པ</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation>པར་རིས་འདེམས་པ།</translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>ས་གནས་ཀྱི་རི་མོ།</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>དྲ་ཐོག་པར་རིས།</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>བསྐྱར་དུ་ཁ་ཆད་དང་འགལ་བའི་གནས་</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>སོ་སྔོན་པོ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>སོ་སྔོན་པོའི་སྡེབ་སྦྱོར་ཡོ་བྱད་ལ་ཞིབ་དཔྱད་ཚད་ལེན་མ་བྱས་ན། བཀོད་སྤྱོད་བྱེད་ཐབས་མེད།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>སྒོ་རྒྱག་འཆར་ཆས་</translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>འབྲེལ་ལྡན་སྒྲིག་འགོད་</translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>ཉི་ནུབ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>སྒྲིག་ཆས་གདམ་ག་གནང་རོགས།</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>བརྙན་ཤེལ་གྱི་བརྙན་ཤེལ་འཕྲུལ་ཆས།</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">སྒྱིད་ལུག་གི་དུས་ཚོད།</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">བརྙན་ཤེལ་ལ་སྐུལ་སློང་བྱེད་སྐབས་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག་པ།</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་འཆར་གཞི།</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">ལྟ་ཚུལ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>ཡུལ་སྲོལ་གོམས་གཤིས་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5སྐར་མ་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10སྐར་མ་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15སྐར་མ་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30སྐར་མ་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1ཆུ་ཚོད།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>གཏན་ནས་བྱེད་མི་</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་འབྱུང་ཁུངས།</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">བདམས་ཐོན་བྱུང་བ།</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་བརྙན་ཤེལ་གྲོན་ཆུང་བྱེད་མཁན་བདམས་པ་</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">གོ་གནས་ནི། </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">ཡིག་ཆའི་མིང་ནི། </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">ཕྱིར་འཐེན།</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">བརྗེ་རེས་བྱེད་པའི་དུས་ཚོད།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1སྐར་མ་</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">སྲོལ་ཡིག</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">སྐབས་བསྟུན་རང་བཞིན།</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">སྐབས་བསྟུན་གྱིས་བརྗེ་རེས་བྱེད་པ</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">ཡི་གེ(ཆེས་མང་ན་ཡི་གེ་30ཡོད་པ་གཤམ་གསལ། )</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">ངལ་གསོའི་དུས་ཚོད་མངོན་པ།</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">ཡི་གེའི་གོ་གནས།</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">ལྟེ་བར་འཛིན་པ།</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">ལན་ཏུའོ་(ལྦུ་བ་ཅན་གྱི་ཡི་གེ)</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>སྒྱིད་ལུག་གི་དུས་ཚོད།</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>བརྙན་ཤེལ་གྱི་འཆར་གཞི།</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>བརྙན་ཤེལ་གྱི་འབྱུང་ཁུངས།</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>བདམས་ཐོན་བྱུང་བ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>སྲོལ་ཡིག</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>སྐབས་བསྟུན་རང་བཞིན།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>སྐབས་བསྟུན་གྱིས་བརྗེ་རེས་བྱེད་པ</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>བརྗེ་རེས་བྱེད་པའི་དུས་ཚོད།</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>ཡི་གེ(ཆེས་མང་ན་ཡི་གེ་30ཡོད་པ་གཤམ་གསལ། )</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>ཡི་གེའི་གོ་གནས།</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>ལྟེ་བར་འཛིན་པ།</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>ལན་ཏུའོ་(ལྦུ་བ་ཅན་གྱི་ཡི་གེ)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>ངལ་གསོའི་དུས་ཚོད་མངོན་པ།</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་བརྙན་ཤེལ་གྲོན་ཆུང་བྱེད་མཁན་བདམས་པ་</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>གོ་གནས་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>ཡིག་ཆའི་མིང་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>ཕྱིར་འཐེན།</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/de.ts b/ukccplugins_i18n_ts/de.ts +new file mode 100644 +index 0000000..372401b +--- /dev/null ++++ b/ukccplugins_i18n_ts/de.ts +@@ -0,0 +1,642 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="de"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>Bildschirmsperre</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">Nachricht auf dem Sperrbildschirm anzeigen</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">浏览</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">线上图片</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">Lokale Bilder</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">Online-Bilder</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">Auf Standard zurücksetzen</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">Verwandte Einstellungen</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Verzögerung des Sperrbildschirms</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Bild der Bildschirmsperre beim Screenlogin anzeigen</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Nie</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>Hintergrunddateien (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1min</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5min</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10min</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 Minuten</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45 Minuten</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 Stunde</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 Stunden</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 Stunden</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>Wählen Sie eine benutzerdefinierte Hintergrundbilddatei aus</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>Auswählen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>Position: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>Dateiname: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>Dateityp: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>Abbrechen</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">Monitor aus</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">Bildschirmschoner</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">Garnitur</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished">Bild der Bildschirmsperre beim Screenlogin anzeigen</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished">Bildschirmsperre</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished">Lokale Bilder</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished">Online-Bilder</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished">Auf Standard zurücksetzen</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished">蓝牙</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished">Monitor aus</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Bildschirmschoner</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished">Verwandte Einstellungen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished">Garnitur</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>Bildschirmschoner</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">Stillstandszeit</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">Sperrbildschirm beim Aktivieren des Bildschirmschoners</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Bildschirmschoner-Programm</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Sperrbildschirm beim Starten des Bildschirmschoners</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">Ansehen</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">Text (bis zu 30 Zeichen):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">Ruhezeit anzeigen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>Anpassen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5min</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10min</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 Minuten</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 Minuten</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 Stunde</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">Quelle des Bildschirmschoners</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">Auswählen</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Hintergrundbilder (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">Benutzerdefiniertes Bildschirmschoner-Verzeichnis auswählen</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">Position: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">Dateiname: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">Dateityp: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">Abbrechen</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">Schaltzeit</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1min</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">Ordinale</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">Zufällige Umschaltung</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">Position des Textes</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">Zentriert</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">Randow(Sprechblasentext)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Zufällig</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>Nie</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Bildschirmschoner</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished">Stillstandszeit</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished">Bildschirmschoner-Programm</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished">Quelle des Bildschirmschoners</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished">Auswählen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished">Ordinale</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished">Zufällig</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished">Zufällige Umschaltung</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished">Schaltzeit</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished">Text (bis zu 30 Zeichen):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished">Position des Textes</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished">Zentriert</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished">Randow(Sprechblasentext)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished">Ruhezeit anzeigen</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished">Hintergrundbilder (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished">Benutzerdefiniertes Bildschirmschoner-Verzeichnis auswählen</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished">Position: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished">Dateiname: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished">Dateityp: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished">Abbrechen</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/en.ts b/ukccplugins_i18n_ts/en.ts +new file mode 100644 +index 0000000..fe95e83 +--- /dev/null ++++ b/ukccplugins_i18n_ts/en.ts +@@ -0,0 +1,314 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/en_US.ts b/ukccplugins_i18n_ts/en_US.ts +new file mode 100644 +index 0000000..e66da77 +--- /dev/null ++++ b/ukccplugins_i18n_ts/en_US.ts +@@ -0,0 +1,319 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/es.ts b/ukccplugins_i18n_ts/es.ts +new file mode 100644 +index 0000000..05fb99a +--- /dev/null ++++ b/ukccplugins_i18n_ts/es.ts +@@ -0,0 +1,642 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="es"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>Bloqueo de pantalla</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">Mostrar mensaje en la pantalla de bloqueo</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">浏览</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">线上图片</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">Fotos locales</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">Imágenes en línea</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">Restablecer a los valores predeterminados</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">Ajustes relacionados</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Retraso de la pantalla de bloqueo</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Mostrar imagen de bloqueo de pantalla en el inicio de sesión en pantalla</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Nunca</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1 minuto</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5 minutos</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10 minutos</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 minutos</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45min</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 hora</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 horas</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 horas</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>Seleccionar archivo de fondo de pantalla personalizado</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>Escoger</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>Posición: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>Nombre: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>Tipo de archivo: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>Cancelar</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">Monitor apagado</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">Protector de pantalla</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">Poner</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished">Mostrar imagen de bloqueo de pantalla en el inicio de sesión en pantalla</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished">Bloqueo de pantalla</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished">Fotos locales</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished">Imágenes en línea</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished">Restablecer a los valores predeterminados</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished">蓝牙</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished">Monitor apagado</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Protector de pantalla</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished">Ajustes relacionados</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished">Poner</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>Protector de pantalla</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">Tiempo de inactividad</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">Pantalla de bloqueo al activar el protector de pantalla</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Programa protector de pantalla</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Pantalla de bloqueo al arrancar el protector de pantalla</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">Vista</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">Texto (hasta 30 caracteres):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">Mostrar tiempo de descanso</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>Personalizar</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 minutos</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 minutos</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 minutos</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 minutos</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 hora</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">Fuente del protector de pantalla</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">Escoger</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jfpe * .gif * .tif * .tiff *.wdp * .svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">Seleccione el directorio del protector de pantalla personalizado</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">Posición: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">Nombre: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">Tipo de archivo: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">Cancelar</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">Tiempo de conmutación</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1 minuto</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">Ordinal</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">Conmutación aleatoria</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">Posición del texto</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">Centrado</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">Randow(Texto de burbuja)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Aleatorio</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>Nunca</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Protector de pantalla</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished">Tiempo de inactividad</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished">Programa protector de pantalla</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished">Fuente del protector de pantalla</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished">Escoger</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished">Ordinal</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished">Aleatorio</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished">Conmutación aleatoria</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished">Tiempo de conmutación</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished">Texto (hasta 30 caracteres):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished">Posición del texto</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished">Centrado</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished">Randow(Texto de burbuja)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished">Mostrar tiempo de descanso</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished">Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jfpe * .gif * .tif * .tiff *.wdp * .svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished">Seleccione el directorio del protector de pantalla personalizado</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished">Posición: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished">Nombre: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished">Tipo de archivo: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished">Cancelar</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/fa.ts b/ukccplugins_i18n_ts/fa.ts +new file mode 100644 +index 0000000..cf62757 +--- /dev/null ++++ b/ukccplugins_i18n_ts/fa.ts +@@ -0,0 +1,314 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="fa"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/fr.ts b/ukccplugins_i18n_ts/fr.ts +new file mode 100644 +index 0000000..205ce25 +--- /dev/null ++++ b/ukccplugins_i18n_ts/fr.ts +@@ -0,0 +1,642 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="fr"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>Verrouillage de l’écran</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">Afficher le message sur l’écran de verrouillage</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">浏览</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">线上图片</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">Photos locales</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">Photos en ligne</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">Réinitialiser les paramètres par défaut</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">Paramètres associés</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Délai de verrouillage de l’écran</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Afficher l’image du verrouillage de l’écran lors de la connexion à l’écran</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Jamais</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1 min</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5 minutes</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10 minutes</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 minutes</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45 min</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 heure</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 heures</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 heures</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>Sélectionnez le fichier de fond d’écran personnalisé</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>Choisir</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>Position: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>Fichier: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>Type de fichier : </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>Annuler</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">Moniteur éteint</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">Économiseur d’écran</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">Poser</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished">Afficher l’image du verrouillage de l’écran lors de la connexion à l’écran</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished">Verrouillage de l’écran</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished">Photos locales</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished">Photos en ligne</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished">Réinitialiser les paramètres par défaut</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished">蓝牙</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished">Moniteur éteint</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Économiseur d’écran</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished">Paramètres associés</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished">Poser</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>Économiseur d’écran</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">Temps d’inactivité</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">Verrouiller l’écran lors de l’activation de l’économiseur d’écran</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Programme d’économiseur d’écran</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Écran de verrouillage lors du démarrage de l’économiseur d’écran</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">Vue</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">Texte (jusqu’à 30 caractères) :</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">Afficher le temps de repos</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI (en anglais seulement)</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>Personnaliser</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 minutes</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 minutes</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 min</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 minutes</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 heure</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">Source de l’économiseur d’écran</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">Choisir</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff * .wdp * .svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">Sélectionnez le répertoire de l’économiseur d’écran personnalisé</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">Position: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">Fichier: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">Type de fichier : </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">Annuler</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">Temps de commutation</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1 min</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">Ordinal</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">Commutation aléatoire</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">Position du texte</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">Centré</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">Randow(Texte à bulles)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Aléatoire</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>Jamais</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Économiseur d’écran</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished">Temps d’inactivité</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished">Programme d’économiseur d’écran</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished">Source de l’économiseur d’écran</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished">Choisir</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished">Ordinal</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished">Aléatoire</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished">Commutation aléatoire</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished">Temps de commutation</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished">Texte (jusqu’à 30 caractères) :</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished">Position du texte</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished">Centré</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished">Randow(Texte à bulles)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished">Afficher le temps de repos</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished">Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff * .wdp * .svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished">Sélectionnez le répertoire de l’économiseur d’écran personnalisé</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished">Position: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished">Fichier: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished">Type de fichier : </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished">Annuler</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/kk.ts b/ukccplugins_i18n_ts/kk.ts +new file mode 100644 +index 0000000..ce59b1b +--- /dev/null ++++ b/ukccplugins_i18n_ts/kk.ts +@@ -0,0 +1,622 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="kk"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>ەكٸران قۇلىبى</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">Screenlock интерфейсі</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">Құлыптау экранында хабарды көрсету</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">Шолу</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">Онлайн сурет</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">Әдепкіге ысыру</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>TextLabel</source> ++ <translation type="obsolete">TextLabel</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Скриншотты жүктеу кезінде экранды құлыптау</translation> ++ <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Экранның кідіруі</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Скриншот суретін скриншотта көрсету</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Ешқашан</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1 м</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5 м</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10 м</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30 м</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45 м</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>تام قاعازى حۇجاتتارى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="obsolete">1 мин</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="obsolete">5 мин</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="obsolete">1 мин {10m?}</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="obsolete">30 мин</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="obsolete">1 мин {45m?}</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="obsolete">1 нөсер</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="obsolete">1 нөсер {2h?}</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="obsolete">1 нөсер {3h?}</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>ەرەكشە تام قاعازى حۇجاتىن تالداۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>تالداۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>ورنى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>حۇجات مى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>:حۇجات تۇرى </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>كۇشىنەن قالدىرۋ</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>كورسەتۋ ەكرانداعى تام قاعازى كىرۋ كورىنبە بەتىندە</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>قۇلىبىن قالدىرىپ قويۋ (بٸر جۇپ تەلەفون جوعالىپ كەتكەندە سەستيما قۇلىپتالادى)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>بەلگٸلەنگەن اسباب</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>جۇپ تەلەفون جوق 'كۆكچىش' نى قوشۇۋېلىپ قوس.</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>ەكٸران قۇلىبى</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished">جەرلىك راسىمدەر</translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>جەرلىك راسىمدەر</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>تورداعٸ راسىمدەر</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>سۈكۈتكە قايتاي</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>كۆكچىش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>كۆكچىش ۇيلەستىرۋ بايقالمادٸ، Leave Lock نى ٸستەتكەلٸ بولمايدى.</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>قاداعالاۋ ٴوشىرۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>ەكٸران قورعاۋ</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>قاتىناستىق تەڭشەۋلەر</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>بەلگٸلەۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>اسبابٸن تالدا</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>ەكٸران قورعاۋ</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">Бос уақыт</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">Экран қорғаушыны белсендіргенде экранды құлыптау</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Скриншотшы бағдарламасы</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">Көрініс</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">Мәтін (30 таңбаға дейін):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">Демалыс уақытын көрсету</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>دارالاندىرۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>بەس مينۋت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>ون مينۋت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 مينۋت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>وتىز مينۋت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>بٸر ساعات</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">Скриншот көзі</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">Таңдау</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Тұсқағаз файлдары(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">реттелетін скриншот дирін таңдаңыз</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">Лауазымы: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">Файл атауы: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">РаÐ1/2аÐ1/2а </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">Болдырмау</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">Ауыстырып қосу уақыты</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>بٸر مينۋت</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">Ординал</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">Кездейсоқ ауыстырып қосу</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">Мәтін орны</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">Орталықтандырылған</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">Randow(Көпіршікті мәтін)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Кездейсоқ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>ماڭگى</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>ەكٸران قورعاۋ</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>بوس ۋاقىتى</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>ەكٸران قورعاۋ پىروگىرامماسى</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>ەكٸران بەتى قاينارى</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>تالداۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>داستۇرلٸ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>ەركىن</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>قالاعانىڭىزشا سايكەستىرۋ</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>سايكەستىرۋ ۋاقىتى</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>تەكىسىت(ەڭ كوپ بولعاندا 30 ٴارىپ):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>تەكىسىت ورنى</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>ورتالىق ورىندالعان</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>ەرٸكتٸ(كوبىكشە تەكىسىت)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>دەمالٸس الۋ ۋاقىتىن كورسەتۋ</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>ەكٸرانٸ كوز بەك سارالاۋعا ەكٸرانٸ قۇلپىلاۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>تام قاعازى حۇجاتتارى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>ەرەكشە ەكٸران باقىلاۋدى تالداۋ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>ورنى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>حۇجات مى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>:حۇجات تۇرى </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>كۇشىنەن قالدىرۋ</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/ky.ts b/ukccplugins_i18n_ts/ky.ts +new file mode 100644 +index 0000000..51b510a +--- /dev/null ++++ b/ukccplugins_i18n_ts/ky.ts +@@ -0,0 +1,622 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="ky"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>ەكىران قۇلۇپى</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">Экран кулпулоо интерфейси</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">Билдирүүлөрдү кулпулоо экранында көрсөтүү</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">Браузер</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">Онлайн сүрөт</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">Дефолтко калыбына келтирүү</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>TextLabel</source> ++ <translation type="obsolete">ТекстЛабель</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Экранды которуу учурунда экранды кулпулоо</translation> ++ <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Экранды кечиктирүү</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Экранлогдо сценарийдин сүрөтүн көрсөтүү</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Эч качан</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1м</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5м</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10м</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30м</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45м</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1х</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2х</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>تام قاعازى ۅجۅتتۅرۉ(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="obsolete">1мин</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="obsolete">5мин</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="obsolete">1мин {10m?}</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="obsolete">30мин</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="obsolete">1мин {45m?}</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="obsolete">1хур</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="obsolete">1хур {2h?}</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="obsolete">1хур {3h?}</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>قاسىيەت تام قاعازى ۅجۅتۉن تانداش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>تانداش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>وردۇ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>ۅجۅت ناامى : </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>:ۅجۅت تۉرۉ </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>ارعادان قالتىرىش</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>كۅرسۅتۉۉ ئېكرانىدىكى تام قاعازى كىرۉۉ كۅرۉنمۅ بەتىندە</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>قۇلۇپنى قالتىرىپ قويۇش (بىر جۇپ ەسەپتەمەك جوعولۇپ كەتكەندە ساامالىق قۇلۇپلىنىدۇ)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>بەلگىلەنگەن شايمان</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>جۇپ تەلەفون جوق 'كۆكچىش' نى قوشۇۋېلىپ قوشۇڭ.</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>ەكىران قۇلۇپى</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>جەردىك سۉرۅتتۅر</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>توردوعۇ سۉرۅتتۅر</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>سۈكۈتكە قايتاي</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>كۆكچىش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>كۆكچىش شايكەشتىرگىچ بايقالبادى، Leave Lock نى ىشتەتكەلى بولبويت .</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>كۉزۅتكۉچتۉ ۅچۉرۉۉ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>ەكىران قورعوو</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>بايلانىشتۇۇ تەڭشەكتەر</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>بەلگىلۅۅ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>اسپاپتى تانداڭ</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>ەكىران قورعوو</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">Бош убакыт</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">Экран сактагычты активдештирүүдө экранды кулпулоо</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Экрандар программасы</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">Көрүү</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">Текст (30 тамгага чейин):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">Эс алуу убактысын көрсөтүү</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>قاسىيەتتەشتىرۉۉ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>بەش مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>ون مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>ئوتتۇز مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>بىر ساات</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">Экрандар булагы</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">Тандоо</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">Wallpaper файлдары (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">колдонуучунун экранды тандап алуу</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">Позиция: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">Файл Аты: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">FileType: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">Жокко чыгаруу</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">Убакытты алмаштыруу</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>بىر مىنۇت</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">Ординал</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">Кокусунан которуу</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">Тексттик позиция</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">Борбордоштурулган</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">Рандоу (Көпірчүк тексти)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Кокусунан</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>تۉبۅلۉك</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>ەكىران قورعوو</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>بەكەر ۇباقتى</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>ەكىران قورعوو پراگرامماسى</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>ەكىران بەتى قاينارى</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>تانداش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>جۅرۅلگۅلۉ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>ۅز ەركىنچە</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>قاالاعانچا الماشتىرۇۇ</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>الماشتىرۇۇ ۇباقتى</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>تەكىست(ەڭ كۅپ بولعوندو 30 تامعا):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>تەكىست وردۇ</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>بوربور اتقارىلعان</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>ۅزەركى مەنەن(كۆپۈكچە تەكىست)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>ەس الۇۇ الۇۇ ۇباقتىن كۅرسۅتۉۉ</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>ەكراندى كۅزۅنۅك جابۇۇدا ەكراندى قۇلۇپتوو</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>تام قاعازى ۅجۅتتۅرۉ(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>قاسىيەت ەكىران كۅرگۉچتۉ تانداش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>وردۇ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>ۅجۅت ناامى : </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>:ۅجۅت تۉرۉ </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>ارعادان قالتىرىش</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/lzh.ts b/ukccplugins_i18n_ts/lzh.ts +new file mode 100644 +index 0000000..0396ee5 +--- /dev/null ++++ b/ukccplugins_i18n_ts/lzh.ts +@@ -0,0 +1,454 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="lzh"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="26"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="45"/> ++ <source>Screenlock</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="80"/> ++ <source>Screenlock Interface</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="205"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="177"/> ++ <source>Show message on lock screen</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="416"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="133"/> ++ <source>Browse</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="423"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="135"/> ++ <source>Online Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="455"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="144"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="332"/> ++ <source>Lock screen delay</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="262"/> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="131"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="476"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/> ++ <source>45min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/> ++ <source>2hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/> ++ <source>3hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="518"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="519"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="520"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="521"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="522"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="523"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="59"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="98"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="201"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="199"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="475"/> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="297"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="197"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="905"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="185"/> ++ <source>View</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="862"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="896"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="226"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="227"/> ++ <source>Blank_Only</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="238"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="765"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="766"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="767"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="667"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="673"/> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="723"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="681"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="722"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="724"/> ++ <source>Position: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="725"/> ++ <source>FileName: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="726"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="727"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="760"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="764"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="812"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="821"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="936"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="944"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="945"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="813"/> ++ <source>Random</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="247"/> ++ <source>Never</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/mn.ts b/ukccplugins_i18n_ts/mn.ts +new file mode 100644 +index 0000000..3b8ae7a +--- /dev/null ++++ b/ukccplugins_i18n_ts/mn.ts +@@ -0,0 +1,638 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="mn"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠴᠣᠣᠵᠢᠯᠠᠬᠤ ᠦᠶᠡᠰ ᠵᠠᠩᠭᠢ ᠢᠯᠡᠷᠡᠭᠦᠯᠬᠦ</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">ᠦᠵᠡ ᠃</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">ᠰᠦᠯᠵᠢᠶᠡᠨ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">ᠲᠤᠰ ᠭᠠᠵᠠᠷᠤ᠋ᠨ ᠵᠢᠷᠤᠭ</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">ᠰᠦᠯᠵᠢᠶᠡᠨ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">ᠠᠶᠠᠳᠠᠯ ᠢ᠋ ᠰᠡᠷᠬᠦᠬᠡᠬᠦ</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">ᠬᠠᠮᠢᠶᠠ ᠪᠦᠬᠦᠢ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭᠠ</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">ᠲᠤᠰ ᠴᠠᠭᠤ᠋ᠨ ᠬᠡᠰᠡᠭᠦ᠋ᠨ ᠠᠷᠤ ᠳᠡᠯᠭᠡᠴᠡ</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">ᠣᠨᠢᠰᠤᠯᠠᠭᠰᠠᠨ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠠᠭᠠᠭ ᠭᠠᠳᠠᠷᠭᠤ ᠳᠡᠭᠡᠷᠡ ᠢᠯᠡᠷᠡᠬᠦ</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">ᠶᠡᠷᠦ ᠡᠴᠡ ᠥᠬᠡᠢ</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 ᠴᠠᠭ</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 ᠴᠠᠭ</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 ᠴᠠᠭ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>ᠰᠣᠩᠭᠣᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>ᠪᠠᠢᠷᠢ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷᠡ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>ᠹᠠᠢᠯ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">ᠦᠵᠡᠬᠦᠷ ᠢ᠋ ᠬᠠᠭᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">ᠣᠴᠢᠵᠤ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠬᠤ</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>ᠣᠨᠢᠰᠤᠯᠠᠭᠰᠠᠨ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠠᠭᠠᠭ ᠭᠠᠳᠠᠷᠭᠤ ᠳᠡᠭᠡᠷᠡ ᠢᠯᠡᠷᠡᠬᠦ</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>ᠣᠨᠢᠰᠤᠯᠠᠯ ᠠᠴᠠ ᠰᠠᠯᠬᠤ ( ᠭᠠᠷ ᠤᠲᠠᠰᠤ ᠠᠷᠢᠯᠤᠭᠰᠠᠨ ᠤ ᠳᠠᠷᠠᠭᠠᠬᠢ ᠰᠢᠰᠲ᠋ᠧᠮ ᠢ ᠲᠣᠭᠲᠠᠭᠠᠨᠠ )</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢ ᠵᠢᠭᠠᠨ ᠲᠣᠭᠲᠠᠭᠠᠨᠠ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>ᠲᠣᠬᠢᠷᠠᠯᠴᠠᠭᠰᠠᠨ ᠭᠠᠷ ᠤᠲᠠᠰᠤ ᠪᠠᠢ᠌ᠬᠤ ᠦᠭᠡᠢ “ ᠬᠥᠬᠡ ᠰᠢᠳᠦ “ᠳᠦ ᠰᠢᠯᠵᠢᠭᠦᠯᠦᠨ ᠲᠣᠬᠢᠷᠠᠭᠤᠯᠤᠭᠠᠷᠠᠢ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>ᠲᠤᠰ ᠭᠠᠵᠠᠷᠤ᠋ᠨ ᠵᠢᠷᠤᠭ</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>ᠱᠤᠭᠤᠮ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>ᠠᠶᠠᠳᠠᠯ ᠢ᠋ ᠰᠡᠷᠬᠦᠬᠡᠬᠦ</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>ᠬᠥᠬᠡ ᠰᠢᠳᠦ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>ᠬᠥᠬᠡ ᠰᠢᠳᠦᠨ ᠦ ᠲᠣᠬᠢᠷᠠᠬᠤ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠪᠠᠶᠢᠴᠠᠭᠠᠨ ᠰᠢᠯᠭᠠᠭᠰᠠᠨ ᠦᠭᠡᠶ ᠪᠣᠯ Leave Lock ᠶᠢ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ ᠶᠢᠨ ᠠᠷᠭᠠ ᠦᠭᠡᠶ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>ᠦᠵᠡᠬᠦᠷ ᠢ᠋ ᠬᠠᠭᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>ᠬᠠᠮᠢᠶᠠ ᠪᠦᠬᠦᠢ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭᠠ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>ᠰᠢᠰᠲ᠋ᠧᠮᠦ᠋ᠨ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭᠠ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢ ᠰᠣᠩᠭᠣᠭᠠᠷᠠᠢ</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">ᠲᠤᠰ ᠴᠠᠭ ᠤ᠋ᠨ ᠬᠡᠰᠡᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡᠶ᠋ᠢ ᠢᠳᠡᠪᠬᠢᠵᠢᠭᠦᠯᠬᠦᠳ᠋ᠦ᠍ ᠳᠡᠯᠭᠡᠴᠡᠶ᠋ᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠫᠷᠣᠭ᠌ᠷᠠᠮ</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ ᠦᠶᠡ ᠳ᠋ᠤ᠌ ᠳᠡᠯᠭᠡᠴᠡ ᠵᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">ᠪᠠᠢᠴᠠᠭᠠᠵᠤ ᠦᠵᠡᠬᠦ</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠲᠸᠺᠰᠲ ( ᠬᠠᠮᠤᠭ ᠤ᠋ᠨ ᠣᠯᠠᠨ ᠳ᠋ᠤ᠌ ᠪᠡᠨ 30 ᠦᠰᠦᠭ):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">ᠠᠮᠠᠷᠠᠬᠤ ᠴᠠᠭ ᠢ᠋ ᠢᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">ᠬᠠᠷᠠ ᠳᠡᠯᠭᠡᠴᠡ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 ᠴᠠᠭ</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠢᠷᠡᠯᠳᠡ</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">ᠰᠤᠩᠭᠤᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢᠨ ᠵᠢᠮ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">ᠪᠠᠢᠷᠢ: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷᠡ: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">ᠳᠠᠪᠳᠠᠮᠵᠢ ᠵᠢ ᠰᠣᠯᠢᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1 ᠮᠢᠨᠦ᠋ᠲ</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">ᠳᠠᠷᠠᠭᠠᠯᠠᠯ ᠵᠢᠡᠷ</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ ᠵᠢᠡᠷ ᠰᠣᠯᠢᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">ᠲᠸᠺᠰᠲ ᠤ᠋ᠨ ᠪᠠᠢᠷᠢ</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">ᠳᠦᠪᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ ( ᠬᠦᠬᠡᠰᠦ ᠲᠸᠺᠰᠲ)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>ᠶᠡᠷᠦ ᠡᠴᠡ ᠥᠬᠡᠢ</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>ᠲᠤᠰ ᠴᠠᠭ ᠤ᠋ᠨ ᠬᠡᠰᠡᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭᠠ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠫᠷᠣᠭ᠌ᠷᠠᠮ</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠢᠷᠡᠯᠳᠡ</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>ᠰᠣᠩᠭᠣᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>ᠳᠠᠷᠠᠭᠠᠯᠠᠯ ᠵᠢᠡᠷ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>ᠳᠠᠰᠢᠷᠠᠮ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>ᠳᠠᠰᠢᠷᠠᠮ ᠵᠢᠡᠷ ᠰᠣᠯᠢᠬᠤ</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>ᠳᠠᠪᠳᠠᠮᠵᠢ ᠵᠢ ᠰᠣᠯᠢᠬᠤ</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠲᠸᠺᠰᠲ ( ᠬᠠᠮᠤᠭ ᠤ᠋ᠨ ᠣᠯᠠᠨ ᠳ᠋ᠤ᠌ ᠪᠡᠨ 30 ᠦᠰᠦᠭ):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>ᠲᠸᠺᠰᠲ ᠤ᠋ᠨ ᠪᠠᠢᠷᠢ</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>ᠳᠦᠪᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>ᠳᠠᠰᠢᠷᠠᠮ ( ᠬᠦᠬᠡᠰᠦ ᠲᠸᠺᠰᠲ)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>ᠠᠮᠠᠷᠠᠬᠤ ᠴᠠᠭ ᠢ᠋ ᠢᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ ᠦᠶᠡ ᠳ᠋ᠤ᠌ ᠳᠡᠯᠭᠡᠴᠡ ᠵᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢᠨ ᠵᠢᠮ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>ᠪᠠᠢᠷᠢ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷᠡ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>ᠹᠠᠢᠯ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/tr.ts b/ukccplugins_i18n_ts/tr.ts +new file mode 100644 +index 0000000..4fc5b4d +--- /dev/null ++++ b/ukccplugins_i18n_ts/tr.ts +@@ -0,0 +1,499 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="tr_TR"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>Ekran kilidi</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">Ekran Kilidi Arayüzü</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">Ekran Kilidi Ayarı</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Ekran koruyucu açıldığında ekranı kilitle</translation> ++ <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">Ekran kilidi gecikmesi</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">Dk</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">Kilit Ekranı Arkaplanını Seç</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">İnternetten Al</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">Bilgisayardan Ekle</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">Ekran girişinde ekran kilidinin resmini göster</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">Ekran kilidi aktif</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">Aç</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">Ekran kilidi</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">Resim</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">Asla</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5 dk</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10 dk</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30 dk</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45 dk</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1 dk</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1 sa</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5 sa</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3 sa</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="obsolete">3 sa {2h?}</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation type="unfinished">Duvarkağıdı Dosyaları(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="obsolete">Tüm Dosyalar(*.*)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation type="unfinished">Özel duvar kağıdı dosyasını seç</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation type="unfinished">Konum: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation type="unfinished">Dosya Adı: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation type="unfinished">İptal</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="obsolete">Ayarla</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished">Ekran girişinde ekran kilidinin resmini göster</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished">Ekran kilidi</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Ekran Koruyucu</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished">Ayarla</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>Ekran Koruyucu</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">Ekran Koruyucu Aktif</translation> ++ <extra-contents_path>/screensaver/Enable screensaver</extra-contents_path> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">Ekran Koruyucu Programı</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">Bekleme Süresi</translation> ++ <extra-contents_path>/screensaver/idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">Dk</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">Ekran koruyucu açıldığında ekranı kilitle</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">Ekran Koruyucu</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">Ukui Varsayılanı</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Sadece Kalın</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="obsolete">Konum: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="obsolete">Dosya Adı: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="obsolete">İptal</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">Rasgele</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>Asla</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5 dk</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10 dk</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30 dk</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45 dk</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1 dk</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1 sa</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5 sa</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3 sa</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished">Ekran Koruyucu</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished">Ekran Koruyucu Programı</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished">Rasgele</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished">Ekran koruyucu açıldığında ekranı kilitle</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished">Konum: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished">Dosya Adı: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished">İptal</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/ug.ts b/ukccplugins_i18n_ts/ug.ts +new file mode 100644 +index 0000000..b5fbfd2 +--- /dev/null ++++ b/ukccplugins_i18n_ts/ug.ts +@@ -0,0 +1,626 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="ug"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>ئېكران قۇلۇپى</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">ئېكران قۇلۇپى ئارايۈز</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">قۇلۇپ ئېكرانىدا ئۇچۇر كۆرسىتىش</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">كۆرۈش</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">توردا رەسىم</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">سۈكۈتكە قايتاي</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>TextLabel</source> ++ <translation type="obsolete">TextLabel</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">ئېكراننى كۆزنەك تاقاشتا ئېكراننى قۇلۇپلاش</translation> ++ <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">قۇلۇپ ئېكرانى كېچىكتۈرۈش</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">screenlogin دا ئېكران قۇلۇپىنىڭ سۈرىتىنى كۆرسىتىش پروگراممىسى</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">مەڭگۈ</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1م</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5م</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10م</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30م</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45م</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1ھ</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3ھ</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2ھ</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="obsolete">1min</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="obsolete">5min</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="obsolete">10min</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="obsolete">30min</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="obsolete">1min {45m?}</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="obsolete">1ھۇدا</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="obsolete">1ھۇدا {2h?}</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="obsolete">1ھۇدا {3h?}</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>خاس تام قەغىزى ھۆججىتىنى تاللاش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>تاللاش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>ئورنى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>ھۆججەت نامى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>:ھۆججەت تۈرى </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>ئەمەلدىن قالدۇرۇش</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>كۆرسىتىش ئېكرانىدىكى تام قەغىزى كىرىش كۆرۈنمە يۈزىدە</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>قۇلۇپنى قالدۇرۇپ قويۇش (بىر جۈپ يانفون يوقاپ كەتكەندە سىستېما قۇلۇپلىنىدۇ)</translation> ++ <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>بەلگىلەنگەن ئۈسكۈنە</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>جۈپ تېلېفون يوق 'كۆكچىش' نى قوشۇۋېلىپ قوشۇڭ.</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>ئېكران قۇلۇپى</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>يەرلىك رەسىملەر</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>توردىكى رەسىملەر</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>سۈكۈتكە قايتاي</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>كۆكچىش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>كۆكچىش ماسلاشتۇرغۇچ بايقالمىدى، Leave Lock نى ئىشلەتكىلى بولمايدۇ.</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>كۆزەتكۈچنى ئۆچۈرۈش</translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>ئېكران قوغداش</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>مۇناسىۋەتلىك تەڭشەكلەر</translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>بەلگىلەش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>ئۈسكۈنىنى تاللاڭ</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>ئېكران قوغداش</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">بىكار ۋاقتى</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">ئېكران ئېكرانىنى قوزغىتىپ تۇرغاندا ئېكراننى قۇلۇپلاش</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">ئېكران ئېكرانى پروگراممىسى</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">كۆرۈش</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">تېكىست(ئەڭ كۆپ بولغاندا 30 ھەرپ):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">ئارام ئېلىش ۋاقتىنى كۆرسىتىش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">Blank_Only</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>خاسلاشتۇرۇش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>بەش مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>ئون مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>ئوتتۇز مىنۇت</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>بىر سائەت</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">ئېكران يۈزى مەنبەسى</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">تاللاش</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">خاس ئېكران كۆرگۈچ dir نى تاللاش</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">ئورنى: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">ھۆججەت نامى: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">FileType: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">ئەمەلدىن قالدۇرۇش</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">ئالماشتۇرۇش ۋاقتى</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>بىر مىنۇت</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">ئوردىدا</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">خالىغانچە ئالماشتۇرۇش</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">تېكىست ئورنى</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">مەركەز قىلىنغان</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">رانۋېر (كۆپۈكچە تېكىست)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">ئىختىيارىي</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>مەڭگۈ</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>ئېكران قوغداش</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>بىكار ۋاقتى</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>ئېكران قوغداش پىروگراممىسى</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>ئېكران يۈزى مەنبەسى</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>تاللاش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>ئەنئەنىۋى</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>ئىختىيارىي</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>خالىغانچە ئالماشتۇرۇش</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>ئالماشتۇرۇش ۋاقتى</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>تېكىست(ئەڭ كۆپ بولغاندا 30 ھەرپ):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>تېكىست ئورنى</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>مەركەز قىلىنغان</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>ئىختىيارى(كۆپۈكچە تېكىست)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>ئارام ئېلىش ۋاقتىنى كۆرسىتىش</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>ئېكراننى كۆزنەك تاقاشتا ئېكراننى قۇلۇپلاش</translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>خاس ئېكران كۆرگۈچنى تاللاش</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>ئورنى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>ھۆججەت نامى: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>:ھۆججەت تۈرى </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>ئەمەلدىن قالدۇرۇش</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/zh_CN.ts b/ukccplugins_i18n_ts/zh_CN.ts +new file mode 100644 +index 0000000..88926f7 +--- /dev/null ++++ b/ukccplugins_i18n_ts/zh_CN.ts +@@ -0,0 +1,623 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="zh_CN"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>锁屏</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ <extra-contents_path>/Screenlock/Screenlock Interface</extra-contents_path> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">锁屏时显示消息</translation> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">相关设置</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">此时间段后锁屏</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">显示锁屏壁纸在登录界面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">从不</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>图片文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1分钟</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5分钟</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10分钟</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30分钟</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45分钟</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1小时</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2小时</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3小时</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>选择自定义壁纸文件</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>选择</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>位置: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>文件名: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>文件类型: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">关闭显示器</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">屏幕保护</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">去设置</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>显示锁屏壁纸在登录界面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>动态锁 (系统将在已配对的蓝牙手机离开时自动锁定屏幕)</translation> ++ <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation>指定设备</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>无配对手机,请转到 "蓝牙" 以连接手机。</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>锁屏</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation>选择图片</translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>本地图片</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>线上图片</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>恢复默认</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>蓝牙设置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>未检测到蓝牙适配器,无法使用动态锁功能。</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>关闭显示器</translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>屏幕保护</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>相关设置</translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>去设置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>请选择指定设备</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">此时间段后开启屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">激活屏保时锁住屏幕</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">屏幕保护程序</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">预览</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">屏保文本(最多30个字):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">显示休息时间</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">黑屏</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>自定义</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 分钟</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 分钟</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 分钟</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 分钟</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 小时</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">屏保来源</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">选择</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">壁纸文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">选择自定义屏保路径</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">位置:</translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">文件名:</translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">文件类型:</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">取消</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">切换频率</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1分钟</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">按顺序</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">随机切换</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">文本位置</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">居中</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">随机(气泡文本)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">随机</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>从不</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>此时间段后开启屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>屏幕保护程序</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>屏保来源</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>选择</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>按顺序</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>随机</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>随机切换</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>切换频率</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>屏保文本(最多 30 个字):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>文本位置</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>居中</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>随机(气泡文本)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>显示休息时间</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>激活屏保时锁定屏幕</translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>壁纸文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>选择自定义屏保路径</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>位置: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>文件名: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>文件类型: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/zh_HK.ts b/ukccplugins_i18n_ts/zh_HK.ts +new file mode 100644 +index 0000000..9c6dd3a +--- /dev/null ++++ b/ukccplugins_i18n_ts/zh_HK.ts +@@ -0,0 +1,647 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="zh_HK"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>鎖屏</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">鎖屏時顯示消息</translation> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">本地圖片</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">線上圖片</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">恢復預設</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">相關設置</translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">此時間段后鎖屏</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">顯示鎖屏壁紙在登錄介面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">從不</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>圖片檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1 分鐘</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5 分鐘</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10 分鐘</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 分鐘</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45 分鐘</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 小時</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 小時</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 小時</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>選擇自訂壁紙檔</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>選擇</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>位置: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>檔案名稱: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>檔案類型: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">關閉顯示器</translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">屏幕保護</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">去設置</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation>顯示鎖屏壁紙在登錄介面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation>動態鎖(系統將在已配對的藍牙手機離開時自動鎖定屏幕)</translation> ++ <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation>無配對手機,請轉到“藍牙”以鏈接手機</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation>鎖屏</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation>選擇圖片</translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation>本地圖片</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation>線上圖片</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation>恢復預設</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation>蓝牙設置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation>無藍牙適配器,不能使用動態鎖</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation>關閉顯示器</translation> ++ <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ <extra-contents_path>/Screenlock/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation>相關設置</translation> ++ <extra-contents_path>/Screenlock/Related Settings</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation>設置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation>請選擇設備</translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">此時間段后開啟屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">啟動屏保時鎖住螢幕</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">屏幕保護程式</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">啟動屏保時鎖定螢幕</translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">預覽</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">屏保文本(最多 30 個字):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">顯示休息時間</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">黑屏</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>自訂</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 小時</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">屏保來源</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">選擇</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">選擇自訂屏保路徑</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">位置: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">檔案名稱: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">檔案類型: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">取消</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">切換頻率</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1 分鐘</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">按順序</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">隨機切換</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">文本位置</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">居中</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">隨機(氣泡文字)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">隨機</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>從不</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation>此時間段后開啟屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation>屏幕保護程式</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation>屏保來源</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation>選擇</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation>按順序</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation>隨機</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation>隨機切換</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation>切換頻率</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation>屏保文本(最多 30 個字):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation>文本位置</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation>居中</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation>隨機(氣泡文字)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation>顯示休息時間</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation>開啓屏保時鎖定屏幕</translation> ++ <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation>壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation>選擇自訂屏保路徑</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation>位置:</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation>文件名:</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation>文件類型:</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++</context> ++</TS> +diff --git a/ukccplugins_i18n_ts/zh_Hant.ts b/ukccplugins_i18n_ts/zh_Hant.ts +new file mode 100644 +index 0000000..bc71d16 +--- /dev/null ++++ b/ukccplugins_i18n_ts/zh_Hant.ts +@@ -0,0 +1,642 @@ ++<?xml version="1.0" encoding="utf-8"?> ++<!DOCTYPE TS> ++<TS version="2.1" language="zh"> ++<context> ++ <name>Screenlock</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/> ++ <source>Screenlock</source> ++ <translation>鎖屏</translation> ++ </message> ++ <message> ++ <source>Screenlock Interface</source> ++ <translation type="vanished">锁屏界面</translation> ++ </message> ++ <message> ++ <source>Show message on lock screen</source> ++ <translation type="vanished">鎖屏時顯示消息</translation> ++ </message> ++ <message> ++ <source>Browse</source> ++ <translation type="vanished">浏览</translation> ++ <extra-contents_path>/Screenlock/Browse</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Picture</source> ++ <translation type="vanished">线上图片</translation> ++ <extra-contents_path>/Screenlock/Online Picture</extra-contents_path> ++ </message> ++ <message> ++ <source>Local Pictures</source> ++ <translation type="vanished">本地圖片</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Online Pictures</source> ++ <translation type="vanished">線上圖片</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <source>Reset To Default</source> ++ <translation type="vanished">恢復預設</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <source>Related Settings</source> ++ <translation type="vanished">相關設置</translation> ++ </message> ++ <message> ++ <source>Screenlock Set</source> ++ <translation type="vanished">锁屏设置</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">激活屏保时锁定屏幕</translation> ++ </message> ++ <message> ++ <source>Lock screen delay</source> ++ <translation type="vanished">此時間段后鎖屏</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Select screenlock background</source> ++ <translation type="vanished">选择锁屏背景</translation> ++ </message> ++ <message> ++ <source>Browser online wp</source> ++ <translation type="vanished">浏览线上壁纸</translation> ++ </message> ++ <message> ++ <source>Browser local wp</source> ++ <translation type="vanished">浏览本地壁纸</translation> ++ </message> ++ <message> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="vanished">顯示鎖屏壁紙在登錄介面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <source>Enabel screenlock</source> ++ <translation type="vanished">开启锁屏</translation> ++ </message> ++ <message> ++ <source>Open</source> ++ <translation type="obsolete">浏览</translation> ++ </message> ++ <message> ++ <source>screenlock</source> ++ <translation type="vanished">锁屏</translation> ++ </message> ++ <message> ++ <source>picture</source> ++ <translation type="obsolete">图片</translation> ++ </message> ++ <message> ++ <source>Never</source> ++ <translation type="vanished">從不</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>2h</source> ++ <translation type="vanished">2h</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source> ++ <translation>圖片檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation> ++ </message> ++ <message> ++ <source>allFiles(*.*)</source> ++ <translation type="vanished">所有文件(*.*)</translation> ++ </message> ++ <message> ++ <source>1min</source> ++ <translation type="vanished">1 分鐘</translation> ++ </message> ++ <message> ++ <source>5min</source> ++ <translation type="vanished">5 分鐘</translation> ++ </message> ++ <message> ++ <source>10min</source> ++ <translation type="vanished">10 分鐘</translation> ++ </message> ++ <message> ++ <source>30min</source> ++ <translation type="vanished">30 分鐘</translation> ++ </message> ++ <message> ++ <source>45min</source> ++ <translation type="vanished">45 分鐘</translation> ++ </message> ++ <message> ++ <source>1hour</source> ++ <translation type="vanished">1 小時</translation> ++ </message> ++ <message> ++ <source>2hour</source> ++ <translation type="vanished">2 小時</translation> ++ </message> ++ <message> ++ <source>3hour</source> ++ <translation type="vanished">3 小時</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/> ++ <source>select custom wallpaper file</source> ++ <translation>選擇自訂壁紙檔</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/> ++ <source>Select</source> ++ <translation>選擇</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/> ++ <source>Position: </source> ++ <translation>位置: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/> ++ <source>FileName: </source> ++ <translation>檔案名稱: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/> ++ <source>FileType: </source> ++ <translation>檔案類型: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Monitor Off</source> ++ <translation type="vanished">關閉顯示器</translation> ++ </message> ++ <message> ++ <source>Screensaver</source> ++ <translation type="vanished">屏幕保護</translation> ++ </message> ++ <message> ++ <source>Set</source> ++ <translation type="vanished">去設置</translation> ++ </message> ++</context> ++<context> ++ <name>ScreenlockUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/> ++ <source>Show picture of screenlock on screenlogin</source> ++ <translation type="unfinished">顯示鎖屏壁紙在登錄介面</translation> ++ <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/> ++ <source>Leave lock (System will be locked when the paired phone gone)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/> ++ <source>Specified device</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/> ++ <source>No paired phone. Please turn to 'Bluetooth' to pair.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/> ++ <source>Screenlock</source> ++ <translation type="unfinished">鎖屏</translation> ++ <extra-contents_path>/Screenlock/Screenlock</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/> ++ <source>Choose Picture</source> ++ <translation type="unfinished">選擇圖片</translation> ++ <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/> ++ <source>Local Pictures</source> ++ <translation type="unfinished">本地圖片</translation> ++ <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/> ++ <source>Online Pictures</source> ++ <translation type="unfinished">線上圖片</translation> ++ <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/> ++ <source>Reset To Default</source> ++ <translation type="unfinished">恢復預設</translation> ++ <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/> ++ <source>Bluetooth</source> ++ <translation type="unfinished">蓝牙</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/> ++ <source>No bluetooth adapter detected, can not use Leave Lock.</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/> ++ <source>Monitor Off</source> ++ <translation type="unfinished">關閉顯示器</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/> ++ <source>Related Settings</source> ++ <translation type="unfinished">相關設置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/> ++ <source>Set</source> ++ <translation type="unfinished">去設置</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/> ++ <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/> ++ <source>Please select device</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>Screensaver</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/> ++ <source>Screensaver</source> ++ <translation>屏保</translation> ++ </message> ++ <message> ++ <source>Idle time</source> ++ <translation type="vanished">此時間段后開啟屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <source>Lock screen when activating screensaver</source> ++ <translation type="vanished">啟動屏保時鎖住螢幕</translation> ++ </message> ++ <message> ++ <source>Enable screensaver</source> ++ <translation type="vanished">开启屏保</translation> ++ </message> ++ <message> ++ <source>Screensaver program</source> ++ <translation type="vanished">屏幕保護程式</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <source>idle time</source> ++ <translation type="vanished">等待时间</translation> ++ </message> ++ <message> ++ <source>Min</source> ++ <translation type="vanished">分钟</translation> ++ </message> ++ <message> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="vanished">啟動屏保時鎖定螢幕</translation> ++ </message> ++ <message> ++ <source>screensaver</source> ++ <translation type="vanished">屏保</translation> ++ </message> ++ <message> ++ <source>Default_ukui</source> ++ <translation type="vanished">默认屏保</translation> ++ </message> ++ <message> ++ <source>View</source> ++ <translation type="vanished">預覽</translation> ++ </message> ++ <message> ++ <source>Text(up to 30 characters):</source> ++ <translation type="vanished">屏保文本(最多 30 個字):</translation> ++ </message> ++ <message> ++ <source>Show rest time</source> ++ <translation type="vanished">顯示休息時間</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>UKUI</source> ++ <translation>UKUI</translation> ++ </message> ++ <message> ++ <source>Blank_Only</source> ++ <translation type="vanished">黑屏</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/> ++ <source>Customize</source> ++ <translation>自訂</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>5min</source> ++ <translation>5 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>10min</source> ++ <translation>10 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>15min</source> ++ <translation>15 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>30min</source> ++ <translation>30 分鐘</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>1hour</source> ++ <translation>1 小時</translation> ++ </message> ++ <message> ++ <source>Screensaver source</source> ++ <translation type="vanished">屏保來源</translation> ++ </message> ++ <message> ++ <source>Select</source> ++ <translation type="vanished">選擇</translation> ++ </message> ++ <message> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="vanished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <source>select custom screensaver dir</source> ++ <translation type="vanished">選擇自定義屏保路徑</translation> ++ </message> ++ <message> ++ <source>Position: </source> ++ <translation type="vanished">位置: </translation> ++ </message> ++ <message> ++ <source>FileName: </source> ++ <translation type="vanished">檔案名稱: </translation> ++ </message> ++ <message> ++ <source>FileType: </source> ++ <translation type="vanished">檔案類型: </translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation type="vanished">取消</translation> ++ </message> ++ <message> ++ <source>Switching time</source> ++ <translation type="vanished">切換頻率</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/> ++ <source>1min</source> ++ <translation>1 分鐘</translation> ++ </message> ++ <message> ++ <source>Ordinal</source> ++ <translation type="vanished">按順序</translation> ++ </message> ++ <message> ++ <source>Random switching</source> ++ <translation type="vanished">隨機切換</translation> ++ </message> ++ <message> ++ <source>Display text</source> ++ <translation type="vanished">显示文本</translation> ++ </message> ++ <message> ++ <source>Enter text, up to 30 characters</source> ++ <translation type="vanished">输入文本,最多30个字符</translation> ++ </message> ++ <message> ++ <source>Text position</source> ++ <translation type="vanished">文本位置</translation> ++ </message> ++ <message> ++ <source>Centered</source> ++ <translation type="vanished">居中</translation> ++ </message> ++ <message> ++ <source>Randow(Bubble text)</source> ++ <translation type="vanished">隨機(氣泡文字)</translation> ++ </message> ++ <message> ++ <source>1m</source> ++ <translation type="vanished">1m</translation> ++ </message> ++ <message> ++ <source>5m</source> ++ <translation type="vanished">5m</translation> ++ </message> ++ <message> ++ <source>10m</source> ++ <translation type="vanished">10m</translation> ++ </message> ++ <message> ++ <source>30m</source> ++ <translation type="vanished">30m</translation> ++ </message> ++ <message> ++ <source>45m</source> ++ <translation type="vanished">45m</translation> ++ </message> ++ <message> ++ <source>1h</source> ++ <translation type="vanished">1h</translation> ++ </message> ++ <message> ++ <source>1.5h</source> ++ <translation type="vanished">1.5h</translation> ++ </message> ++ <message> ++ <source>3h</source> ++ <translation type="vanished">3h</translation> ++ </message> ++ <message> ++ <source>Random</source> ++ <translation type="vanished">隨機</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/> ++ <source>Never</source> ++ <translation>從不</translation> ++ </message> ++</context> ++<context> ++ <name>ScreensaverUi</name> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/> ++ <source>Screensaver</source> ++ <translation type="unfinished"></translation> ++ <extra-contents_path>/Screensaver/Screensaver</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/> ++ <source>Idle time</source> ++ <translation type="unfinished">此時間段后開啟屏保</translation> ++ <extra-contents_path>/Screensaver/Idle time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/> ++ <source>Screensaver program</source> ++ <translation type="unfinished">屏幕保護程式</translation> ++ <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/> ++ <source>Screensaver source</source> ++ <translation type="unfinished">屏保來源</translation> ++ <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/> ++ <source>Select</source> ++ <translation type="unfinished">選擇</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/> ++ <source>Ordinal</source> ++ <translation type="unfinished">按順序</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/> ++ <source>Random</source> ++ <translation type="unfinished">隨機</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/> ++ <source>Random switching</source> ++ <translation type="unfinished">隨機切換</translation> ++ <extra-contents_path>/Screensaver/Random switching</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/> ++ <source>Switching time</source> ++ <translation type="unfinished">切換頻率</translation> ++ <extra-contents_path>/Screensaver/Switching time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/> ++ <source>Text(up to 30 characters):</source> ++ <translation type="unfinished">屏保文本(最多 30 個字):</translation> ++ <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/> ++ <source>Text position</source> ++ <translation type="unfinished">文本位置</translation> ++ <extra-contents_path>/Screensaver/Text position</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/> ++ <source>Centered</source> ++ <translation type="unfinished">居中</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/> ++ <source>Randow(Bubble text)</source> ++ <translation type="unfinished">隨機(氣泡文字)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/> ++ <source>Show rest time</source> ++ <translation type="unfinished">顯示休息時間</translation> ++ <extra-contents_path>/Screensaver/Show rest time</extra-contents_path> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/> ++ <source>Lock screen when screensaver boot</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/> ++ <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source> ++ <translation type="unfinished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/> ++ <source>select custom screensaver dir</source> ++ <translation type="unfinished">選擇自定義屏保路徑</translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/> ++ <source>Position: </source> ++ <translation type="unfinished">位置: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/> ++ <source>FileName: </source> ++ <translation type="unfinished">檔案名稱: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/> ++ <source>FileType: </source> ++ <translation type="unfinished">檔案類型: </translation> ++ </message> ++ <message> ++ <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/> ++ <source>Cancel</source> ++ <translation type="unfinished">取消</translation> ++ </message> ++</context> ++</TS> diff -Nru ukui-screensaver-4.20.0.0/debian/patches/series ukui-screensaver-4.20.0.0/debian/patches/series --- ukui-screensaver-4.20.0.0/debian/patches/series 2024-12-17 13:37:23.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/patches/series 2025-02-13 20:26:40.000000000 +0800 @@ -1,2 +1,7 @@ 0001-107.patch 0002-109.patch +0003-ok.patch +0004-sysc-codes-from-v11-2503.patch +0005-sync-codes-from-v11-2503.patch +0006-112-sync-codes-from-v11-2503.patch +0007-114-update-changelog.patch diff -Nru ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst --- ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst 2024-12-17 13:37:23.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst 2025-02-13 20:26:40.000000000 +0800 @@ -5,6 +5,18 @@ glib-compile-schemas /usr/share/glib-2.0/schemas/ +path_conf="/usr/share/lightdm/lightdm.conf.d/95-ukui-greeter.conf" +dpkg-divert --package ukui-screensaver --rename --remove "$path_conf".old +path_sh="/usr/lib/lightdm/lightdm-session-setup.sh " +dpkg-divert --package ukui-screensaver --rename --remove "$path_sh".old +path_desktop="/usr/share/xgreeters/ukui-greeter.desktop" +dpkg-divert --package ukui-screensaver --rename --remove "$path_desktop".old + +path_sl_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreenlock.so" +dpkg-divert --package ukui-screensaver --rename --remove "$path_sl_plugin".old +path_ss_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreensaver.so" +dpkg-divert --package ukui-screensaver --rename --remove "$path_ss_plugin".old + if [ -x /usr/share/kylin-system-updater/kylin-reboot-required ]; then #执行请求重启提示 /usr/share/kylin-system-updater/kylin-reboot-required diff -Nru ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst --- ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst 2024-12-17 13:37:23.000000000 +0800 +++ ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst 2025-02-13 20:26:40.000000000 +0800 @@ -16,3 +16,10 @@ #} #remove_greeter() + +# dpkg rename ukui-control-center's libscreensaver.so and libscreenlock.so +path_sl_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreenlock.so" +dpkg-divert --package ukui-screensaver --rename --divert "$path_sl_plugin"".old" --add $path_sl_plugin +path_ss_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreensaver.so" +dpkg-divert --package ukui-screensaver --rename --divert "$path_ss_plugin"".old" --add $path_ss_plugin +