2023-04-11 10:19:35 +08:00
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2023, KylinSoft Co., Ltd.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2022-06-28 11:20:36 +08:00
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
#include <qt5xdg/XdgDesktopFile>
|
|
|
|
|
#include <QMutexLocker>
|
|
|
|
|
#include <QCryptographicHash>
|
|
|
|
|
#include <QFile>
|
2023-08-15 17:34:41 +08:00
|
|
|
|
#include <KWindowSystem>
|
|
|
|
|
#include "appdatabaseadaptor.h"
|
|
|
|
|
#include "file-utils.h"
|
|
|
|
|
#include "application-property-helper.h"
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-08-08 13:55:51 +08:00
|
|
|
|
#define GENERAL_APP_DESKTOP_PATH "/usr/share/applications"
|
|
|
|
|
#define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications"
|
|
|
|
|
#define SNAPD_APP_DESKTOP_PATH "/var/lib/snapd/desktop/applications"
|
2022-06-13 13:38:47 +08:00
|
|
|
|
|
2022-06-23 10:21:22 +08:00
|
|
|
|
#define LAST_LOCALE_NAME QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/last-locale-name.conf"
|
|
|
|
|
#define LOCALE_NAME_VALUE "CurrentLocaleName"
|
2022-12-21 11:04:37 +08:00
|
|
|
|
#define APP_DATABASE_VERSION_CONFIG QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/app-database-version.conf"
|
|
|
|
|
#define APP_DATABASE_VERSION_VALUE "AppDatabaseVersion"
|
2023-04-17 16:14:44 +08:00
|
|
|
|
static const QString AUTOSTART_APP_DESKTOP_PATH = "/etc/xdg/autostart";
|
2022-06-23 10:21:22 +08:00
|
|
|
|
using namespace UkuiSearch;
|
|
|
|
|
|
|
|
|
|
static AppDBManager *global_instance;
|
2022-07-12 11:26:03 +08:00
|
|
|
|
QMutex AppDBManager::s_mutex;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
AppDBManager *AppDBManager::getInstance()
|
|
|
|
|
{
|
|
|
|
|
if (!global_instance) {
|
|
|
|
|
global_instance = new AppDBManager();
|
|
|
|
|
}
|
|
|
|
|
return global_instance;
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-06-28 14:00:57 +08:00
|
|
|
|
AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDatabase())
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2022-06-23 10:21:22 +08:00
|
|
|
|
//链接数据库
|
|
|
|
|
if (openDataBase()) {
|
2023-03-15 11:32:42 +08:00
|
|
|
|
//建数据库
|
|
|
|
|
buildAppInfoDB();
|
|
|
|
|
|
2022-06-23 10:21:22 +08:00
|
|
|
|
//监听系统语言变化
|
2022-12-21 11:04:37 +08:00
|
|
|
|
m_lastLocaleNameQsettings = new QSettings(LAST_LOCALE_NAME, QSettings::IniFormat);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
m_localeChanged = false;
|
2022-12-21 11:04:37 +08:00
|
|
|
|
m_lastLocaleNameQsettings->beginGroup(LOCALE_NAME_VALUE);
|
|
|
|
|
QString lastLocale = m_lastLocaleNameQsettings->value(LOCALE_NAME_VALUE).toString();
|
2022-06-23 10:21:22 +08:00
|
|
|
|
if (QLocale::system().name().compare(lastLocale)) {
|
|
|
|
|
qDebug() << "I'm going to update the locale name in conf file.";
|
|
|
|
|
if (!lastLocale.isEmpty()) {
|
|
|
|
|
m_localeChanged = true;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-12-21 11:04:37 +08:00
|
|
|
|
m_lastLocaleNameQsettings->setValue(LOCALE_NAME_VALUE, QLocale::system().name());
|
|
|
|
|
}
|
|
|
|
|
m_lastLocaleNameQsettings->endGroup();
|
|
|
|
|
|
|
|
|
|
//检查数据库版本
|
|
|
|
|
m_dbVersionQsettings = new QSettings(APP_DATABASE_VERSION_CONFIG, QSettings::IniFormat);
|
|
|
|
|
m_dbVersionQsettings->beginGroup(APP_DATABASE_VERSION_VALUE);
|
|
|
|
|
QString dbVersion = m_dbVersionQsettings->value(APP_DATABASE_VERSION_VALUE).toString();
|
|
|
|
|
if (dbVersion.isEmpty()) {
|
|
|
|
|
m_dbVersionNeedUpdate = true;
|
2023-03-10 17:47:04 +08:00
|
|
|
|
} else if (dbVersion != APP_DATABASE_VERSION) {
|
2022-12-21 11:04:37 +08:00
|
|
|
|
if (dbVersion.toDouble() < APP_DATABASE_VERSION.toDouble()) {
|
|
|
|
|
m_dbVersionNeedUpdate = true;
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "app db version old version:" << dbVersion.toDouble() << "new version:" << APP_DATABASE_VERSION.toDouble();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_dbVersionQsettings->endGroup();
|
|
|
|
|
|
|
|
|
|
if (m_dbVersionNeedUpdate) {
|
|
|
|
|
qDebug() << "app db version need update! old version:" << dbVersion.toDouble() << "new version:" << APP_DATABASE_VERSION.toDouble();
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-15 11:32:42 +08:00
|
|
|
|
//版本号改变更新数据库字段
|
|
|
|
|
if (m_dbVersionNeedUpdate) {
|
|
|
|
|
for (auto iter = m_namesOfAppinfoTable.constBegin(); iter!= m_namesOfAppinfoTable.constEnd(); iter++) {
|
|
|
|
|
this->addItem2BackIfNotExist(iter.key(), iter.value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//刷新应用数据
|
2023-03-10 17:47:04 +08:00
|
|
|
|
QStringList appPaths;
|
|
|
|
|
appPaths << GENERAL_APP_DESKTOP_PATH << ANDROID_APP_DESKTOP_PATH
|
|
|
|
|
<< SNAPD_APP_DESKTOP_PATH << AUTOSTART_APP_DESKTOP_PATH;
|
2023-03-22 15:47:27 +08:00
|
|
|
|
refreshAllData2DB(appPaths, m_dbVersionNeedUpdate);
|
2022-12-21 11:04:37 +08:00
|
|
|
|
|
|
|
|
|
if (m_dbVersionNeedUpdate) {
|
|
|
|
|
m_dbVersionQsettings->beginGroup(APP_DATABASE_VERSION_VALUE);
|
|
|
|
|
m_dbVersionQsettings->setValue(APP_DATABASE_VERSION_VALUE, APP_DATABASE_VERSION);
|
|
|
|
|
m_dbVersionQsettings->endGroup();
|
|
|
|
|
m_dbVersionNeedUpdate = false;
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-08-08 13:55:51 +08:00
|
|
|
|
//初始化FileSystemWatcher
|
2023-03-15 11:32:42 +08:00
|
|
|
|
initFileSystemWatcher();
|
2022-08-08 13:55:51 +08:00
|
|
|
|
|
|
|
|
|
/*
|
2022-06-23 10:21:22 +08:00
|
|
|
|
//初始化FileSystemWatcher
|
|
|
|
|
m_watchAppDir = new QFileSystemWatcher(this);
|
|
|
|
|
m_watchAppDir->addPath(GENERAL_APP_DESKTOP_PATH);
|
|
|
|
|
QDir androidPath(ANDROID_APP_DESKTOP_PATH);
|
|
|
|
|
if(!androidPath.exists()) {
|
|
|
|
|
androidPath.mkpath(ANDROID_APP_DESKTOP_PATH);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
m_watchAppDir->addPath(ANDROID_APP_DESKTOP_PATH);
|
|
|
|
|
|
|
|
|
|
QDir snapdPath(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
if(!snapdPath.exists()) {
|
|
|
|
|
snapdPath.mkpath(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
}
|
|
|
|
|
m_watchAppDir->addPath(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
|
2022-06-28 14:00:57 +08:00
|
|
|
|
//初始化timer
|
|
|
|
|
this->start();
|
|
|
|
|
m_timer = new QTimer();
|
|
|
|
|
m_maxProcessTimer = new QTimer();
|
|
|
|
|
|
|
|
|
|
m_timer->setInterval(2*1000);
|
|
|
|
|
m_maxProcessTimer->setInterval(5*1000);
|
|
|
|
|
|
|
|
|
|
m_timer->setSingleShot(true);
|
|
|
|
|
m_maxProcessTimer->setSingleShot(true);
|
|
|
|
|
|
|
|
|
|
m_timer->moveToThread(this);
|
|
|
|
|
m_maxProcessTimer->moveToThread(this);
|
|
|
|
|
|
|
|
|
|
connect(this, SIGNAL(startTimer()), m_timer, SLOT(start()));
|
|
|
|
|
connect(this, SIGNAL(maxProcessTimerStart()), m_maxProcessTimer, SLOT(start()));
|
|
|
|
|
connect(this, &AppDBManager::stopTimer, m_timer, &QTimer::stop);
|
|
|
|
|
connect(this, &AppDBManager::stopTimer, m_maxProcessTimer, &QTimer::stop);
|
|
|
|
|
|
|
|
|
|
//监听desktop文件所在目录,由于directoryChange会发多次信号,使用计时器阻塞
|
2022-06-23 10:21:22 +08:00
|
|
|
|
connect(m_watchAppDir, &QFileSystemWatcher::directoryChanged, this, [ = ](const QString & path) {
|
|
|
|
|
qDebug() << "m_watchAppDir directoryChanged:" << path;
|
2022-06-28 14:00:57 +08:00
|
|
|
|
Q_EMIT this->startTimer();
|
|
|
|
|
if (!m_maxProcessTimer->isActive()) {
|
|
|
|
|
Q_EMIT this->maxProcessTimerStart();
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2022-06-28 14:00:57 +08:00
|
|
|
|
//计时器超时统一进行更新操作
|
|
|
|
|
connect(m_timer, &QTimer::timeout, this, [ & ] {
|
|
|
|
|
qDebug() << "Time out! Now I can update the database!";
|
|
|
|
|
Q_EMIT this->stopTimer();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
this->refreshAllData2DB();
|
2022-06-28 14:00:57 +08:00
|
|
|
|
}, Qt::DirectConnection);
|
|
|
|
|
connect(m_maxProcessTimer, &QTimer::timeout, this, [ & ] {
|
|
|
|
|
qDebug() << "I've waited too lang, I have to update the database now!";
|
|
|
|
|
Q_EMIT this->stopTimer();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
this->refreshAllData2DB();
|
2022-06-28 14:00:57 +08:00
|
|
|
|
}, Qt::DirectConnection);
|
2022-08-08 13:55:51 +08:00
|
|
|
|
*/
|
2022-06-28 14:00:57 +08:00
|
|
|
|
|
2022-06-23 10:21:22 +08:00
|
|
|
|
//监控应用进程开启
|
|
|
|
|
connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) {
|
2023-08-08 17:00:31 +08:00
|
|
|
|
QDBusVariant dbusVariant(id);
|
|
|
|
|
QString desktopFilePath = this->tranWinIdToDesktopFilePath(dbusVariant);
|
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
|
|
|
|
this->updateLaunchTimes(desktopFilePath);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2023-08-15 17:34:41 +08:00
|
|
|
|
new AppDBManagerAdaptor(this);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "App-db-manager does nothing.";
|
|
|
|
|
}
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AppDBManager::~AppDBManager()
|
|
|
|
|
{
|
2022-08-08 13:55:51 +08:00
|
|
|
|
if (m_watcher) {
|
|
|
|
|
delete m_watcher;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-08-08 13:55:51 +08:00
|
|
|
|
m_watcher = NULL;
|
|
|
|
|
|
|
|
|
|
if (m_snapdWatcher) {
|
|
|
|
|
delete m_snapdWatcher;
|
|
|
|
|
}
|
|
|
|
|
m_snapdWatcher = NULL;
|
|
|
|
|
|
|
|
|
|
// if(m_watchAppDir) {
|
|
|
|
|
// delete m_watchAppDir;
|
|
|
|
|
// }
|
|
|
|
|
// m_watchAppDir = NULL;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
closeDataBase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDBManager::buildAppInfoDB()
|
|
|
|
|
{
|
2022-07-12 11:26:03 +08:00
|
|
|
|
qDebug() << "I'm going to build app info database.";
|
2022-06-23 10:21:22 +08:00
|
|
|
|
QSqlQuery sql(m_database);
|
2023-04-17 16:14:44 +08:00
|
|
|
|
QString cmd = QString("CREATE TABLE IF NOT EXISTS appInfo(%1, %2, %3, %4, %5, %6, %7, %8,%9, %10, %11, %12, %13, %14, %15, %16, %17, %18, %19, %20, %21, %22)")
|
2022-06-13 13:38:47 +08:00
|
|
|
|
// .arg("ID INT")//自增id
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg("DESKTOP_FILE_PATH TEXT PRIMARY KEY NOT NULL")//desktop文件路径
|
2022-06-13 13:38:47 +08:00
|
|
|
|
.arg("MODIFYED_TIME TEXT")//YYYYMMDDHHmmSS 修改日期
|
|
|
|
|
.arg("INSERT_TIME TEXT")//YYYYMMDDHHmmSS 插入日期
|
|
|
|
|
.arg("LOCAL_NAME TEXT")//本地名称,跟随系统语言
|
|
|
|
|
.arg("NAME_EN TEXT")//应用英文名称
|
|
|
|
|
.arg("NAME_ZH TEXT")//应用中文名称
|
|
|
|
|
.arg("PINYIN_NAME TEXT")//中文拼音
|
|
|
|
|
.arg("FIRST_LETTER_OF_PINYIN TEXT")//中文拼音首字母
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg("FIRST_LETTER_ALL TEXT")//拼音和英文全拼
|
2022-06-13 13:38:47 +08:00
|
|
|
|
.arg("ICON TEXT")//图标名称(或路径)
|
|
|
|
|
.arg("TYPE TEXT")//应用类型
|
|
|
|
|
.arg("CATEGORY TEXT")//应用分类
|
|
|
|
|
.arg("EXEC TEXT")//应用命令
|
|
|
|
|
.arg("COMMENT TEXT")//应用注释
|
|
|
|
|
.arg("MD5 TEXT")//desktop文件内容md5值
|
|
|
|
|
.arg("LAUNCH_TIMES INT")//应用打开次数, 等比例缩减
|
|
|
|
|
.arg("FAVORITES INT")//收藏顺序0:为收藏,>0的数字表示收藏顺序
|
|
|
|
|
.arg("LAUNCHED INT")//应用安装后是否打开过0:未打开过;1:打开过
|
|
|
|
|
.arg("TOP INT")//置顶顺序 0:未置顶;>0的数字表示置顶顺序
|
|
|
|
|
.arg("LOCK INT")//应用是否锁定(管控),0未锁定,1锁定
|
2023-04-17 16:14:44 +08:00
|
|
|
|
.arg("DONT_DISPLAY INT")//应用隐藏(NoDisplay, NotShowIn)
|
|
|
|
|
.arg("AUTO_START INT");//自启应用
|
2022-06-13 13:38:47 +08:00
|
|
|
|
if (!sql.exec(cmd)) {
|
2022-06-23 10:21:22 +08:00
|
|
|
|
qWarning() << m_database.lastError() << cmd;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-15 11:32:42 +08:00
|
|
|
|
void AppDBManager::initFileSystemWatcher()
|
|
|
|
|
{
|
|
|
|
|
m_watcher = new FileSystemWatcher;
|
|
|
|
|
m_watcher->addWatch(GENERAL_APP_DESKTOP_PATH);
|
|
|
|
|
QDir androidDir(ANDROID_APP_DESKTOP_PATH);
|
|
|
|
|
if(!androidDir.exists()) {
|
|
|
|
|
androidDir.mkpath(ANDROID_APP_DESKTOP_PATH);
|
|
|
|
|
}
|
|
|
|
|
m_watcher->addWatch(ANDROID_APP_DESKTOP_PATH);
|
|
|
|
|
|
|
|
|
|
m_snapdDir = new QDir(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
if(!m_snapdDir->exists()) {
|
|
|
|
|
m_snapdWatcher = new FileSystemWatcher(false);
|
|
|
|
|
QDir dir("/var/lib/snapd");
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
dir.setPath("/var/lib");
|
|
|
|
|
}
|
|
|
|
|
m_snapdPath = dir.absolutePath();
|
|
|
|
|
m_snapdWatcher->addWatch(m_snapdPath);
|
|
|
|
|
} else {
|
|
|
|
|
m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_watcher->addWatch(AUTOSTART_APP_DESKTOP_PATH);
|
|
|
|
|
|
|
|
|
|
connect(m_snapdWatcher, &FileSystemWatcher::created, this, [ = ] (const QString &path, bool isDir) {
|
|
|
|
|
if (isDir) {
|
|
|
|
|
//监测新增目录为/var/lib/snapd时,将其替换为snapdWatcher的watchpath
|
|
|
|
|
if (path == "/var/lib/snapd") {
|
|
|
|
|
m_snapdWatcher->removeWatch(m_snapdPath);
|
|
|
|
|
m_snapdWatcher->addWatch(path);
|
|
|
|
|
qDebug() << "~~~~~~~add watch" << path << "~~~~~remove watch" << m_snapdPath;
|
|
|
|
|
m_snapdPath = path;
|
|
|
|
|
//snapd下的desktop目录可能在还没替换监听目录为/var/lib/snapd时就已经被创建,因此需要特别判断
|
|
|
|
|
QDir dir("/var/lib/snapd/desktop");
|
|
|
|
|
if (dir.exists()) {
|
|
|
|
|
if (m_snapdDir->exists()) {
|
|
|
|
|
m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
m_snapdWatcher->removeWatch(m_snapdPath);
|
|
|
|
|
qDebug() << "======add watch" << SNAPD_APP_DESKTOP_PATH << "======remove watch" << m_snapdPath;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//检测到/var/lib/snapd/desktop被创建,则将监听目录替换为/var/lib/snapd/desktop/applications
|
|
|
|
|
if (path == "/var/lib/snapd/desktop" and m_snapdDir->exists()) {
|
|
|
|
|
m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH);
|
|
|
|
|
m_snapdWatcher->removeWatch(m_snapdPath);
|
|
|
|
|
qDebug() << "======add watch" << SNAPD_APP_DESKTOP_PATH << "======remove watch" << m_snapdPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_watcher, &FileSystemWatcher::created, this, [ = ] (const QString &desktopfp, bool isDir) {
|
|
|
|
|
//event is IN_CREATE
|
|
|
|
|
if (!isDir and desktopfp.endsWith(".desktop")) {
|
|
|
|
|
this->insertDBItem(desktopfp);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_watcher, &FileSystemWatcher::moveTo, this, [ = ] (const QString &desktopfp, bool isDir) {
|
|
|
|
|
//event is IN_MOVED_TO
|
|
|
|
|
if (!isDir and desktopfp.endsWith(".desktop")) {
|
|
|
|
|
QStringList appPaths(desktopfp.left(desktopfp.lastIndexOf("/")));
|
|
|
|
|
this->refreshAllData2DB(appPaths);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_watcher, &FileSystemWatcher::modified, this, [ = ] (const QString &desktopfp) {
|
|
|
|
|
//event is IN_MODIFY
|
|
|
|
|
if (desktopfp.endsWith(".desktop")) {
|
|
|
|
|
this->updateDBItem(desktopfp);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_watcher, &FileSystemWatcher::moved, this, [ = ] (const QString &desktopfp, bool isDir) {
|
|
|
|
|
//event is IN_MOVED_FROM
|
|
|
|
|
if (!isDir) {
|
|
|
|
|
if (desktopfp.endsWith(".desktop")) {
|
|
|
|
|
this->deleteDBItem(desktopfp);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//event is IN_MOVE_SELF
|
|
|
|
|
qWarning() << "Dir:" << desktopfp << "has been moved to other place! Stop the watching of the desktop files in it!";
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(m_watcher, &FileSystemWatcher::deleted, this, [ = ] (const QString &desktopfp, bool isDir) {
|
|
|
|
|
//event is IN_DELETE
|
|
|
|
|
if (!isDir) {
|
|
|
|
|
if (desktopfp.endsWith(".desktop")) {
|
|
|
|
|
this->deleteDBItem(desktopfp);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//event is IN_DELETE_SELF
|
|
|
|
|
qWarning() << "Dir:" << desktopfp << "has been deleted! Stop the watching of the desktop files in it!";
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-23 10:21:22 +08:00
|
|
|
|
void AppDBManager::loadDesktopFilePaths(QString path, QFileInfoList &infolist)
|
|
|
|
|
{
|
|
|
|
|
QDir dir(path);
|
|
|
|
|
dir.setSorting(QDir::DirsFirst);
|
|
|
|
|
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
|
|
|
|
infolist.append(dir.entryInfoList());
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-21 11:04:37 +08:00
|
|
|
|
bool AppDBManager::addItem2BackIfNotExist(QString itemName, QString itemDataType, QVariant defult)
|
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
|
|
|
|
QSqlQuery sql(m_database);
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.setForwardOnly(true);
|
|
|
|
|
QString cmd = QString("SELECT * FROM sqlite_master WHERE name = 'appInfo' AND sql like '%%1%' ").arg(itemName);
|
2022-12-21 11:04:37 +08:00
|
|
|
|
if (!sql.exec(cmd)) {
|
|
|
|
|
qWarning() << m_database.lastError() << cmd;
|
|
|
|
|
res = false;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
if (sql.next()) {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qDebug() << itemName << "is exist!";
|
2022-12-21 11:04:37 +08:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-15 11:32:42 +08:00
|
|
|
|
cmd = QString("ALTER TABLE appInfo ADD '%0' %1 ").arg(itemName)
|
|
|
|
|
.arg(itemDataType);
|
2022-12-21 11:04:37 +08:00
|
|
|
|
if (defult != QVariant()) {
|
|
|
|
|
//TODO 根据数据类型将初始值转化为对应格式数据
|
|
|
|
|
if (itemDataType == "INT(4)") {
|
|
|
|
|
cmd += QString("DEFAULT %1").arg(defult.toInt());
|
|
|
|
|
} else if (itemDataType == "TEXT") {
|
|
|
|
|
cmd += QString("DEFAULT %1").arg(QString(defult.toByteArray()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!sql.exec(cmd)) {
|
|
|
|
|
qWarning() << m_database.lastError() << cmd;
|
|
|
|
|
res = false;
|
2023-03-10 17:47:04 +08:00
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "Add item" << itemName << "successful.";
|
2022-12-21 11:04:37 +08:00
|
|
|
|
}
|
|
|
|
|
if (!res) {
|
|
|
|
|
qDebug() << "Fail to addItem2Back :" << itemName;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-22 15:47:27 +08:00
|
|
|
|
void AppDBManager::refreshAllData2DB(const QStringList &appPaths, bool dbVersionNeedUpdate)
|
2022-06-23 10:21:22 +08:00
|
|
|
|
{
|
2023-03-15 11:32:42 +08:00
|
|
|
|
PendingAppInfo items;
|
|
|
|
|
items.setHandleType(PendingAppInfo::RefreshDataBase);
|
|
|
|
|
items.setPathsNeedRefreshData(appPaths);
|
2023-03-22 15:47:27 +08:00
|
|
|
|
items.setDBUpdate(dbVersionNeedUpdate);
|
2023-03-15 11:32:42 +08:00
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(items);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleLocaleDataUpdate(const QString &desktopFilePath)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2022-06-23 10:21:22 +08:00
|
|
|
|
bool res(true);
|
|
|
|
|
XdgDesktopFile desktopFile;
|
2023-03-10 17:47:04 +08:00
|
|
|
|
desktopFile.load(desktopFilePath);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
QString localName = desktopFile.localizedValue("Name", "NULL").toString();
|
|
|
|
|
QString firstLetter2All = localName;
|
|
|
|
|
|
|
|
|
|
if (localName.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) {
|
|
|
|
|
firstLetter2All = FileUtils::findMultiToneWords(localName).at(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.prepare("UPDATE appInfo SET LOCAL_NAME=:localName, FIRST_LETTER_ALL=:firstOfLetter2All WHERE DESKTOP_FILE_PATH=:desktopFilePath");
|
|
|
|
|
query.bindValue(":localName", localName);
|
|
|
|
|
query.bindValue(":firstOfLetter2All", firstLetter2All);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
ApplicationInfoMap appInfo;
|
|
|
|
|
appInfo[desktopFilePath].insert(ApplicationProperty::LocalName, QVariant(localName));
|
|
|
|
|
appInfo[desktopFilePath].insert(ApplicationProperty::FirstLetterAll, QVariant(firstLetter2All));
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(appInfo);
|
|
|
|
|
qDebug() << "Update the locale data of " << desktopFilePath;
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
} else {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qDebug() << "Fail to update the locale data of " << desktopFilePath;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
res = false;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-28 14:00:57 +08:00
|
|
|
|
void AppDBManager::run()
|
|
|
|
|
{
|
|
|
|
|
exec();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDBManager::refreshDataBase()
|
2022-06-23 10:21:22 +08:00
|
|
|
|
{
|
2022-07-12 11:26:03 +08:00
|
|
|
|
// if (m_database.transaction()) {
|
|
|
|
|
// this->updateAllData2DB();
|
|
|
|
|
// if (!m_database.commit()) {
|
|
|
|
|
// qWarning() << "Failed to commit !";
|
|
|
|
|
// m_database.rollback();
|
|
|
|
|
// } else if (!m_dbChanged) {
|
|
|
|
|
// qDebug() << "app DataBase has no changes!";
|
|
|
|
|
// } else {
|
|
|
|
|
// Q_EMIT this->finishHandleAppDB();
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// qWarning() << "Failed to start transaction mode!!!";
|
|
|
|
|
// }
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-23 10:21:22 +08:00
|
|
|
|
bool AppDBManager::openDataBase()
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2022-06-23 10:21:22 +08:00
|
|
|
|
bool res(true);
|
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
QDir dir;
|
|
|
|
|
if (!dir.exists(APP_DATABASE_PATH)) {
|
|
|
|
|
dir.mkpath(APP_DATABASE_PATH);
|
|
|
|
|
}
|
|
|
|
|
if (QSqlDatabase::contains(CONNECTION_NAME)) {
|
2022-06-23 10:21:22 +08:00
|
|
|
|
m_database = QSqlDatabase::database(CONNECTION_NAME);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
} else {
|
2022-06-23 10:21:22 +08:00
|
|
|
|
m_database = QSqlDatabase::addDatabase("QSQLITE", CONNECTION_NAME);
|
|
|
|
|
m_database.setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
if(!m_database.open()) {
|
|
|
|
|
qWarning() << "Fail to open AppDataBase, because" << m_database.lastError();
|
|
|
|
|
res = false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
return res;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDBManager::closeDataBase()
|
|
|
|
|
{
|
2022-06-23 10:21:22 +08:00
|
|
|
|
m_database.close();
|
|
|
|
|
// delete m_database;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
QSqlDatabase::removeDatabase(CONNECTION_NAME);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
QString AppDBManager::getAppDesktopMd5(const QString &desktopfd)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
|
|
|
|
QString res;
|
|
|
|
|
QFile file(desktopfd);
|
|
|
|
|
file.open(QIODevice::ReadOnly);
|
|
|
|
|
res = QString::fromStdString(QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5).toHex().toStdString());
|
|
|
|
|
file.close();
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
bool AppDBManager::startTransaction()
|
|
|
|
|
{
|
|
|
|
|
if (m_database.transaction()) {
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Failed to start transaction mode!!!" << m_database.lastError();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AppDBManager::startCommit()
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2022-07-12 11:26:03 +08:00
|
|
|
|
if (!m_database.commit()) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Failed to commit !" << m_database.lastError();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
m_database.rollback();
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
QSqlQuery sql(m_database);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
XdgDesktopFile desktopfile;
|
2023-03-10 17:47:04 +08:00
|
|
|
|
desktopfile.load(desktopFilePath);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
QString hanzi, pinyin, firstLetterOfPinyin;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
QString localName = desktopfile.localizedValue("Name", "NULL").toString();
|
2022-06-28 11:20:36 +08:00
|
|
|
|
QString firstLetter2All = localName;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
bool isHanzi = true;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
|
|
|
|
if (localName.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) {
|
2022-06-28 11:20:36 +08:00
|
|
|
|
firstLetter2All = FileUtils::findMultiToneWords(localName).at(0);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
if (desktopfile.contains("Name[zh_CN]")) {
|
|
|
|
|
hanzi = desktopfile.value("Name[zh_CN]").toString();
|
|
|
|
|
} else {
|
|
|
|
|
hanzi = desktopfile.value("Name").toString();
|
|
|
|
|
if (!hanzi.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) {
|
|
|
|
|
isHanzi = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
if (isHanzi) {
|
|
|
|
|
QStringList pinyinList = FileUtils::findMultiToneWords(hanzi);
|
|
|
|
|
for (int i = 0; i<pinyinList.size(); ++i) {
|
2022-06-23 10:21:22 +08:00
|
|
|
|
if (i % 2) {
|
2022-06-13 13:38:47 +08:00
|
|
|
|
firstLetterOfPinyin += pinyinList.at(i);
|
|
|
|
|
} else {
|
|
|
|
|
pinyin += pinyinList.at(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
int dontDisplay = 0;
|
2023-04-17 16:14:44 +08:00
|
|
|
|
if (desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
dontDisplay = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-17 16:14:44 +08:00
|
|
|
|
int isAutoStartApp = 0;
|
|
|
|
|
if (desktopFilePath.startsWith(AUTOSTART_APP_DESKTOP_PATH + "/")) {
|
|
|
|
|
isAutoStartApp = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.prepare(QString("INSERT INTO appInfo "
|
|
|
|
|
"(DESKTOP_FILE_PATH, MODIFYED_TIME, INSERT_TIME, "
|
|
|
|
|
"LOCAL_NAME, NAME_EN, NAME_ZH, PINYIN_NAME, "
|
|
|
|
|
"FIRST_LETTER_OF_PINYIN, FIRST_LETTER_ALL, "
|
|
|
|
|
"ICON, TYPE, CATEGORY, EXEC, COMMENT, MD5, "
|
2023-08-08 17:00:31 +08:00
|
|
|
|
"LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY, AUTO_START, START_UP_WMCLASS) "
|
2023-03-10 17:47:04 +08:00
|
|
|
|
"VALUES(:desktopFilePath, '%0', '%1', :localName, :enName, :zhName, :pinyinName, :firstLetterOfPinyin, :firstLetter2All, "
|
2023-08-08 17:00:31 +08:00
|
|
|
|
":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8,%9, :wmClass)")
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(getAppDesktopMd5(desktopFilePath))
|
|
|
|
|
.arg(0)
|
|
|
|
|
.arg(0)
|
|
|
|
|
.arg(0)
|
|
|
|
|
.arg(0)
|
|
|
|
|
.arg(0)
|
2023-04-17 16:14:44 +08:00
|
|
|
|
.arg(dontDisplay)
|
|
|
|
|
.arg(isAutoStartApp));
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
sql.bindValue(":localName", localName);
|
|
|
|
|
sql.bindValue(":enName", desktopfile.value("Name").toString());
|
|
|
|
|
sql.bindValue(":zhName", hanzi);
|
|
|
|
|
sql.bindValue(":pinyinName", pinyin);
|
|
|
|
|
sql.bindValue(":firstLetterOfPinyin", firstLetterOfPinyin);
|
|
|
|
|
sql.bindValue(":firstLetter2All", firstLetter2All);
|
|
|
|
|
sql.bindValue(":icon", desktopfile.value("Icon").toString());
|
|
|
|
|
sql.bindValue(":type", desktopfile.value("Type").toString());
|
|
|
|
|
sql.bindValue(":categories", desktopfile.value("Categories").toString());
|
|
|
|
|
sql.bindValue(":exec", desktopfile.value("Exec").toString());
|
|
|
|
|
sql.bindValue(":comment", desktopfile.value("Comment").toString());
|
2023-08-08 17:00:31 +08:00
|
|
|
|
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
|
2023-03-10 17:47:04 +08:00
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
|
|
|
|
|
if (sql.exec()) {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
Q_EMIT this->appDBItemAdd(desktopFilePath);
|
|
|
|
|
qDebug() << "app database add " << desktopFilePath << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-06-13 13:38:47 +08:00
|
|
|
|
} else {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qDebug() << "app database add " << desktopFilePath << "failed!";
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << m_database.lastError() << sql.lastQuery();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
res = false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleDBItemDelete(const QString &desktopFilePath)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
bool res(true);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
2023-03-10 17:47:04 +08:00
|
|
|
|
QString cmd = "SELECT FAVORITES, TOP FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath";
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
2022-06-28 14:00:57 +08:00
|
|
|
|
|
|
|
|
|
//查询要删除信息的应用是否被收藏或顶置过
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << m_database.lastError() << query.lastQuery();
|
|
|
|
|
} else if (query.next()) {
|
|
|
|
|
int favorites = query.value("FAVORITES").toInt();
|
|
|
|
|
int top = query.value("TOP").toInt();
|
2022-06-28 14:00:57 +08:00
|
|
|
|
if (favorites) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare(QString("UPDATE appInfo SET FAVORITES = FAVORITES -1 WHERE FAVORITES > %1").arg(favorites));
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH,FAVORITES FROM APPINFO WHERE FAVORITES >= %1").arg(favorites);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
ApplicationInfoMap infos;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
if (query.value("DESKTOP_FILE_PATH").toString() == desktopFilePath) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Favorites, query.value("FAVORITES"));
|
|
|
|
|
}
|
|
|
|
|
if (!infos.isEmpty()) {
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(infos);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << "I'm going to delete item in db, fail to update the FAVORITES because:" << query.lastError() << cmd;
|
2022-06-28 14:00:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (top) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare(QString("UPDATE appInfo SET TOP = TOP -1 WHERE TOP > %1").arg(top));
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH,TOP FROM APPINFO WHERE TOP >= %1").arg(top);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
ApplicationInfoMap infos;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
if (query.value("DESKTOP_FILE_PATH").toString() == desktopFilePath) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Top, query.value("TOP"));
|
|
|
|
|
}
|
|
|
|
|
if (!infos.isEmpty()) {
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(infos);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << "I'm going to delete item in db, fail to update the TOP because:" << query.lastError() << cmd;
|
2022-06-28 14:00:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Fail to exec next, because" << query.lastError() << "while executing " << query.lastQuery();
|
2022-06-28 14:00:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!res) {
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
return res;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2022-06-28 14:00:57 +08:00
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
//执行删除操作
|
|
|
|
|
cmd = "DELETE FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath";
|
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
Q_EMIT this->appDBItemDelete(desktopFilePath);
|
|
|
|
|
qDebug() << "app database delete " << desktopFilePath << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-06-13 13:38:47 +08:00
|
|
|
|
} else {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qDebug() << "app database delete " << desktopFilePath << "failed!";
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << query.lastError() << cmd;
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
res = false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
|
|
|
|
XdgDesktopFile desktopfile;
|
2023-03-10 17:47:04 +08:00
|
|
|
|
desktopfile.load(desktopFilePath);
|
2023-04-17 16:14:44 +08:00
|
|
|
|
|
|
|
|
|
int dontDisplay = 0;
|
|
|
|
|
if (desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
dontDisplay = 1;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2023-04-17 16:14:44 +08:00
|
|
|
|
|
|
|
|
|
int isAutoStartApp = 0;
|
|
|
|
|
if (desktopFilePath.startsWith(AUTOSTART_APP_DESKTOP_PATH + "/")) {
|
|
|
|
|
isAutoStartApp = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
QString hanzi, pinyin, firstLetterOfPinyin;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
QString localName = desktopfile.localizedValue("Name", "NULL").toString();
|
|
|
|
|
QString firstLetter2All = localName;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
bool isHanzi = true;
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
|
|
|
|
if (localName.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) {
|
|
|
|
|
firstLetter2All = FileUtils::findMultiToneWords(localName).at(0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
if (desktopfile.contains("Name[zh_CN]")) {
|
|
|
|
|
hanzi = desktopfile.value("Name[zh_CN]").toString();
|
|
|
|
|
} else {
|
|
|
|
|
hanzi = desktopfile.value("Name").toString();
|
|
|
|
|
if (!hanzi.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) {
|
|
|
|
|
isHanzi = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
2022-06-13 13:38:47 +08:00
|
|
|
|
if (isHanzi) {
|
|
|
|
|
QStringList pinyinList = FileUtils::findMultiToneWords(hanzi);
|
2022-06-23 10:21:22 +08:00
|
|
|
|
firstLetter2All = pinyinList.at(0);
|
2022-06-13 13:38:47 +08:00
|
|
|
|
for (int i = 0; i<pinyinList.size(); ++i) {
|
2022-06-23 10:21:22 +08:00
|
|
|
|
if (i % 2) {
|
2022-06-13 13:38:47 +08:00
|
|
|
|
firstLetterOfPinyin += pinyinList.at(i);
|
|
|
|
|
} else {
|
|
|
|
|
pinyin += pinyinList.at(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-23 10:21:22 +08:00
|
|
|
|
|
|
|
|
|
QSqlQuery sql(m_database);
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.prepare(QString("UPDATE appInfo SET "
|
|
|
|
|
"MODIFYED_TIME='%0',"
|
|
|
|
|
"LOCAL_NAME=:localName,"
|
|
|
|
|
"NAME_EN=:enName,"
|
|
|
|
|
"NAME_ZH=:zhName,"
|
|
|
|
|
"PINYIN_NAME=:pinyinName,"
|
|
|
|
|
"FIRST_LETTER_OF_PINYIN=:firstLetterOfPinyin,"
|
|
|
|
|
"FIRST_LETTER_ALL=:firstLetter2All,"
|
|
|
|
|
"ICON=:icon,"
|
|
|
|
|
"TYPE=:type,"
|
|
|
|
|
"CATEGORY=:categories,"
|
|
|
|
|
"EXEC=:exec,"
|
|
|
|
|
"COMMENT=:comment,"
|
2023-08-08 17:00:31 +08:00
|
|
|
|
"START_UP_WMCLASS=:wmClass,"
|
2023-03-10 17:47:04 +08:00
|
|
|
|
"MD5='%1',"
|
2023-04-17 16:14:44 +08:00
|
|
|
|
"DONT_DISPLAY=%2,"
|
|
|
|
|
"AUTO_START=%3 "
|
2023-03-10 17:47:04 +08:00
|
|
|
|
"WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(getAppDesktopMd5(desktopFilePath))
|
2023-04-17 16:14:44 +08:00
|
|
|
|
.arg(dontDisplay)
|
|
|
|
|
.arg(isAutoStartApp));
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
sql.bindValue(":localName", localName);
|
|
|
|
|
sql.bindValue(":enName", desktopfile.value("Name").toString());
|
|
|
|
|
sql.bindValue(":zhName", hanzi);
|
|
|
|
|
sql.bindValue(":pinyinName", pinyin);
|
|
|
|
|
sql.bindValue(":firstLetterOfPinyin", firstLetterOfPinyin);
|
|
|
|
|
sql.bindValue(":firstLetter2All", firstLetter2All);
|
|
|
|
|
sql.bindValue(":icon", desktopfile.value("Icon").toString());
|
|
|
|
|
sql.bindValue(":type", desktopfile.value("Type").toString());
|
|
|
|
|
sql.bindValue(":categories", desktopfile.value("Categories").toString());
|
|
|
|
|
sql.bindValue(":exec", desktopfile.value("Exec").toString());
|
|
|
|
|
sql.bindValue(":comment", desktopfile.value("Comment").toString());
|
2023-08-08 17:00:31 +08:00
|
|
|
|
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
|
2023-03-10 17:47:04 +08:00
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
|
|
|
|
|
if (sql.exec()) {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
Q_EMIT this->appDBItemUpdateAll(desktopFilePath);
|
|
|
|
|
qDebug() << "app database update all data of" << desktopFilePath << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-06-13 13:38:47 +08:00
|
|
|
|
} else {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qDebug() << "app database update " << desktopFilePath << "failed!";
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << m_database.lastError() << sql.lastQuery();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
res = false;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleLaunchTimesUpdate(const QString &desktopFilePath, int num)
|
2022-06-13 13:38:47 +08:00
|
|
|
|
{
|
2022-07-14 19:01:56 +08:00
|
|
|
|
qDebug() << "launch times will add:" << num;
|
2022-06-13 13:38:47 +08:00
|
|
|
|
bool res(true);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
query.prepare("SELECT LAUNCH_TIMES FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath");
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (query.next()) {
|
|
|
|
|
int launchTimes = query.value(0).toInt() + num;
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
res = false;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
query.prepare(QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(launchTimes)
|
|
|
|
|
.arg(1));
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
qWarning() << "Set app launch times failed!" << m_database.lastError();
|
2022-06-13 13:38:47 +08:00
|
|
|
|
res = false;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
m_database.rollback();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
ApplicationInfoMap appInfo;
|
|
|
|
|
appInfo[desktopFilePath].insert(ApplicationProperty::LaunchTimes, QVariant(launchTimes));
|
|
|
|
|
appInfo[desktopFilePath].insert(ApplicationProperty::Launched, QVariant(1));
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(appInfo);
|
|
|
|
|
qDebug() << "app database update " << desktopFilePath << "launch times: " << launchTimes << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-06-13 13:38:47 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Failed to exec next!" << query.lastQuery() << query.lastError();
|
2022-06-13 13:38:47 +08:00
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Failed to exec:" << query.lastQuery();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
res = false;
|
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopFilePath, const uint num)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
2023-02-15 17:17:11 +08:00
|
|
|
|
QString cmd;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
ApplicationInfoMap infos;
|
|
|
|
|
|
|
|
|
|
//获取应用在数据库中的favorites标志位
|
2023-04-23 16:27:45 +08:00
|
|
|
|
uint previousPos = 0;
|
|
|
|
|
bool getPrevious(false);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = "SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH =:desktopFilePath";
|
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (query.next()) {
|
2023-04-23 16:27:45 +08:00
|
|
|
|
previousPos = query.value("FAVORITES").toUInt();
|
|
|
|
|
getPrevious = true;
|
2023-02-15 17:17:11 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//收藏位未改变
|
2023-04-23 16:27:45 +08:00
|
|
|
|
if (getPrevious && previousPos == num) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << "favorites state has no changes, I quit!";
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//查询目前favorites最大值
|
2023-04-23 16:27:45 +08:00
|
|
|
|
uint maxFavorite = 0;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare("SELECT max(FAVORITES) as max FROM APPINFO");
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (query.next()) {
|
2023-04-23 16:27:45 +08:00
|
|
|
|
maxFavorite = query.value("max").toUInt();
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (maxFavorite + 1 < num) {
|
|
|
|
|
qWarning() << QString("Max favorites pos is %0.To be moved to a invalid pos, I quit!!").arg(query.value("max").toInt());
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
if (!res) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//取消收藏时,将对应应用前移
|
|
|
|
|
if (!num) {
|
|
|
|
|
if (previousPos < 1) {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
if (res) {
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
res = false;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=FAVORITES-1 WHERE FAVORITES > %1;")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(previousPos);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH,FAVORITES FROM APPINFO WHERE FAVORITES >= %0;").arg(previousPos);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
qDebug() << "Prepare to cancel the favorite state of" << desktopFilePath;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Favorites, query.value("FAVORITES"));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//直接设置时(要设置的应用未被收藏),查询要设置的favorites标志位是否被占用,占用则将该应用及其之后的应用的favorites标志位后移
|
2023-04-23 16:27:45 +08:00
|
|
|
|
if (getPrevious && !previousPos) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO WHERE FAVORITES = %1").arg(num);
|
|
|
|
|
if (!query.exec(cmd)) {
|
|
|
|
|
qWarning() << "Fail to exec:" << cmd << "because:" << query.lastError();
|
|
|
|
|
res = false;
|
|
|
|
|
} else {
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (query.next()) {
|
|
|
|
|
//默认收藏后顶到第一个,其余后移,若想直接收藏到对应位置则将该位置后的收藏应用后移
|
|
|
|
|
query.prepare(QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=FAVORITES+1 WHERE FAVORITES >= %1;")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(num));
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
m_database.rollback();
|
2023-02-15 17:17:11 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH, FAVORITES FROM APPINFO WHERE FAVORITES >= %1").arg(num);
|
|
|
|
|
if (!query.exec(cmd)) {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
} else {
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Favorites, query.value("FAVORITES"));
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-15 17:17:11 +08:00
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
} else {
|
|
|
|
|
//触发修改位置逻辑
|
|
|
|
|
res = maxFavorite < num? false : this->handleChangeFavoritesPos(desktopFilePath, num, previousPos, infos);
|
|
|
|
|
qDebug() << "change favorites pos:" << res;
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
//移动位置执行不成功则不去更新对应应用的favorites标志位
|
|
|
|
|
if (!res) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
|
2023-02-15 17:17:11 +08:00
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
//更新favorites状态
|
2023-03-10 17:47:04 +08:00
|
|
|
|
cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
2022-07-12 11:26:03 +08:00
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg(num);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (!query.exec()) {
|
2022-07-12 11:26:03 +08:00
|
|
|
|
qWarning() << "Set app favorites state failed!" << m_database.lastError();
|
|
|
|
|
res = false;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
m_database.rollback();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
infos[desktopFilePath].insert(ApplicationProperty::Favorites, QVariant(num));
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(infos);
|
|
|
|
|
qDebug() << "app database update " << desktopFilePath << "favorites state: " << num << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-23 16:27:45 +08:00
|
|
|
|
bool AppDBManager::handleChangeFavoritesPos(const QString &desktopFilePath, const uint pos, const uint previousPos, ApplicationInfoMap &updatedInfo)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (pos < 1) {
|
|
|
|
|
qWarning() << "To be moved to a invalid favorites pos , I quit!!";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (previousPos < 1) {
|
|
|
|
|
qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopFilePath);
|
2022-07-12 11:26:03 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool res(true);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
|
|
|
|
|
QString condition;
|
|
|
|
|
if (previousPos > pos) {
|
|
|
|
|
condition = "FAVORITES=FAVORITES+1";
|
|
|
|
|
} else {
|
|
|
|
|
condition = "FAVORITES=FAVORITES-1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query.prepare(QString("UPDATE APPINFO SET %0 WHERE FAVORITES BETWEEN MIN(%1, %2) AND MAX(%1, %2)")
|
|
|
|
|
.arg(condition)
|
|
|
|
|
.arg(previousPos)
|
|
|
|
|
.arg(pos));
|
|
|
|
|
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新原位置和新位置之间的应用的位置
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
query.prepare(QString("SELECT DESKTOP_FILE_PATH,FAVORITES FROM APPINFO WHERE FAVORITES BETWEEN MIN(%1, %2) AND MAX(%1, %2)")
|
|
|
|
|
.arg(previousPos)
|
|
|
|
|
.arg(pos));
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
updatedInfo[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Favorites, query.value("FAVORITES"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << "Fail to change favorite-app pos, because: " << query.lastError() << " when exec :" << query.lastQuery();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
bool AppDBManager::handleTopStateUpdate(const QString &desktopFilePath, const uint num)
|
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
2023-02-15 17:17:11 +08:00
|
|
|
|
QString cmd;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
ApplicationInfoMap infos;
|
|
|
|
|
|
|
|
|
|
//获取应用在数据库中的top标志位
|
2023-04-23 16:27:45 +08:00
|
|
|
|
uint previousPos = 0;
|
|
|
|
|
bool getPrevious(false);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = "SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH =:desktopFilePath";
|
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (query.next()) {
|
2023-04-23 16:27:45 +08:00
|
|
|
|
previousPos = query.value("TOP").toUInt();
|
|
|
|
|
getPrevious = true;
|
2023-02-15 17:17:11 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//top位未改变
|
2023-04-23 16:27:45 +08:00
|
|
|
|
if (getPrevious && previousPos == num) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << "Top state has no changes, I quit!";
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//查询目前top最大值
|
2023-04-23 16:27:45 +08:00
|
|
|
|
uint maxTop = 0;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare("SELECT max(TOP) as max FROM APPINFO");
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
if (query.next()) {
|
2023-04-23 16:27:45 +08:00
|
|
|
|
maxTop = query.value("max").toUInt();
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (maxTop + 1 < num) {
|
|
|
|
|
qWarning() << QString("Max top pos is %0.To be moved to a invalid pos, I quit!!").arg(query.value("max").toInt());
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
if (!res) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//取消置顶时,将对应应用前移
|
|
|
|
|
if (!num) {
|
|
|
|
|
if (previousPos < 1) {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
if (res) {
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
res = false;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=TOP-1 WHERE TOP > %1;")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(previousPos);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH,TOP FROM APPINFO WHERE TOP >= %0;").arg(previousPos);
|
|
|
|
|
if (query.exec(cmd)) {
|
|
|
|
|
qDebug() << "Prepare to cancel the top state of" << desktopFilePath;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Top, query.value("TOP"));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
qWarning() << query.lastQuery() << query.lastError();
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//直接设置时,查询要设置的top标志位是否被占用,占用则将该应用及其之后的应用的top标志位后移
|
2023-04-23 16:27:45 +08:00
|
|
|
|
if (getPrevious && !previousPos) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO WHERE TOP = %1").arg(num);
|
|
|
|
|
if (!query.exec(cmd)) {
|
|
|
|
|
qWarning() << "Fail to exec:" << cmd << "because:" << query.lastError();
|
|
|
|
|
} else {
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (query.next()) {
|
|
|
|
|
//默认置顶后顶到第一个,其余后移,若想直接置顶到对应位置则将该位置后的置顶应用后移
|
|
|
|
|
query.prepare(QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=TOP+1 WHERE TOP >= %1;")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(num));
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
m_database.rollback();
|
2023-02-15 17:17:11 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
cmd = QString("SELECT DESKTOP_FILE_PATH, TOP FROM APPINFO WHERE TOP >= %1").arg(num);
|
|
|
|
|
if (!query.exec(cmd)) {
|
|
|
|
|
qWarning() << query.lastError() << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
} else {
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
infos[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Top, query.value("TOP"));
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-15 17:17:11 +08:00
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
} else {
|
|
|
|
|
//触发修改位置逻辑
|
|
|
|
|
res = maxTop < num ? false : this->handleChangeTopPos(desktopFilePath, num, previousPos, infos);
|
|
|
|
|
qDebug() << "Change top pos:" << res;
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
//移动位置执行不成功则不去更新对应应用的top标志位
|
|
|
|
|
if (!res) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
|
|
|
|
|
//更新top状态
|
2023-03-10 17:47:04 +08:00
|
|
|
|
cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
2022-07-12 11:26:03 +08:00
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
2023-03-10 17:47:04 +08:00
|
|
|
|
.arg(num);
|
2023-03-31 17:24:06 +08:00
|
|
|
|
query.prepare(cmd);
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
qWarning() << "Set app top state failed!" << query.lastError();
|
|
|
|
|
res = false;
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
} else {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
infos[desktopFilePath].insert(ApplicationProperty::Top, QVariant(num));
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(infos);
|
|
|
|
|
qDebug() << "app database update " << desktopFilePath << "top state: " << num << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2023-03-10 17:47:04 +08:00
|
|
|
|
|
2023-04-23 16:27:45 +08:00
|
|
|
|
bool AppDBManager::handleChangeTopPos(const QString &desktopFilePath, uint pos, const uint previousPos, ApplicationInfoMap &updatedInfo)
|
2023-03-31 17:24:06 +08:00
|
|
|
|
{
|
|
|
|
|
if (pos < 1) {
|
|
|
|
|
qWarning() << "To be moved to a invalid top pos , I quit!!";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (previousPos < 1) {
|
|
|
|
|
qWarning() << QString("app: %1 is not a top app, I quit!!").arg(desktopFilePath);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool res(true);
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
|
|
|
|
|
QString condition;
|
|
|
|
|
if (previousPos > pos) {
|
|
|
|
|
condition = "TOP=TOP+1";
|
|
|
|
|
} else {
|
|
|
|
|
condition = "TOP=TOP-1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
query.prepare(QString("UPDATE APPINFO SET %0 WHERE TOP BETWEEN MIN(%1, %2) AND MAX(%1, %2)")
|
|
|
|
|
.arg(condition)
|
|
|
|
|
.arg(previousPos)
|
|
|
|
|
.arg(pos));
|
|
|
|
|
|
|
|
|
|
if (!this->startTransaction()) {
|
2022-07-12 11:26:03 +08:00
|
|
|
|
res = false;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新原位置和新位置之间的应用的位置
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
query.prepare(QString("SELECT DESKTOP_FILE_PATH,TOP FROM APPINFO WHERE TOP BETWEEN MIN(%1, %2) AND MAX(%1, %2)")
|
|
|
|
|
.arg(previousPos)
|
|
|
|
|
.arg(pos));
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
updatedInfo[query.value("DESKTOP_FILE_PATH").toString()].insert(ApplicationProperty::Top, query.value("TOP"));
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Fail to change favorite-app pos, because: " << query.lastError() << " when exec :" << query.lastQuery();
|
|
|
|
|
res = false;
|
|
|
|
|
m_database.rollback();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
2023-03-31 17:24:06 +08:00
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
bool AppDBManager::handleLockStateUpdate(const QString &desktopFilePath, int num)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
bool res(true);
|
|
|
|
|
QSqlQuery sql(m_database);
|
2023-03-10 17:47:04 +08:00
|
|
|
|
sql.prepare(QString("UPDATE appInfo SET MODIFYED_TIME='%0', LOCK=%1 WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(num));
|
|
|
|
|
sql.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
if (!sql.exec()) {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
qWarning() << "Set app lock state failed!" << m_database.lastError();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
res = false;
|
2023-03-31 17:24:06 +08:00
|
|
|
|
m_database.rollback();
|
2022-07-12 11:26:03 +08:00
|
|
|
|
} else {
|
2023-03-31 17:24:06 +08:00
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
ApplicationInfoMap appInfo;
|
|
|
|
|
appInfo[desktopFilePath].insert(ApplicationProperty::Lock, QVariant(num));
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(appInfo);
|
|
|
|
|
qDebug() << "app database update " << desktopFilePath << "lock state: " << num << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-22 15:47:27 +08:00
|
|
|
|
void AppDBManager::handleDataBaseRefresh(const QStringList &appPaths, bool dbVersionNeedUpdate)
|
2023-03-15 11:32:42 +08:00
|
|
|
|
{
|
|
|
|
|
QMap<QString, QString> dataMap;
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
QString condition;
|
|
|
|
|
for (int i = 0; i < appPaths.size(); i++) {
|
|
|
|
|
condition.append("DESKTOP_FILE_PATH LIKE ? OR ");
|
|
|
|
|
}
|
|
|
|
|
condition = condition.left(condition.lastIndexOf(" OR "));
|
|
|
|
|
query.prepare(QString("SELECT DESKTOP_FILE_PATH,MD5 FROM APPINFO WHERE %0").arg(condition));
|
|
|
|
|
for (int t = 0; t < appPaths.size(); t++) {
|
|
|
|
|
query.bindValue(t, appPaths.at(t) + "/%");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
qWarning() << m_database.lastError() << query.lastError();
|
|
|
|
|
} else {
|
|
|
|
|
query.exec();
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
dataMap.insert(query.value("DESKTOP_FILE_PATH").toString(), query.value("MD5").toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//遍历desktop文件
|
|
|
|
|
QFileInfoList infos;
|
|
|
|
|
for (const QString &path : appPaths) {
|
|
|
|
|
this->loadDesktopFilePaths(path, infos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(infos.size() < 1) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
XdgDesktopFile desktopfile;
|
|
|
|
|
for (int i = 0; i < infos.length(); i++) {
|
|
|
|
|
QFileInfo fileInfo = infos.at(i);
|
|
|
|
|
QString path = fileInfo.filePath();
|
|
|
|
|
//对目录递归
|
|
|
|
|
if (fileInfo.isDir()) {
|
|
|
|
|
loadDesktopFilePaths(path, infos);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
//排除非法路径(非desktop文件)
|
|
|
|
|
if (!path.endsWith(".desktop")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
desktopfile.load(path);
|
|
|
|
|
//排除loaclized名字为空
|
|
|
|
|
if (desktopfile.localizedValue("Name").toString().isEmpty()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!dataMap.isEmpty()) {
|
|
|
|
|
//数据库有记录
|
|
|
|
|
if (dataMap.contains(path)) {
|
2023-03-22 15:47:27 +08:00
|
|
|
|
if (!QString::compare(dataMap.value(path), getAppDesktopMd5(path)) && !dbVersionNeedUpdate) {
|
2023-03-15 11:32:42 +08:00
|
|
|
|
//判断系统语言是否改变
|
|
|
|
|
if (m_localeChanged) {
|
|
|
|
|
this->handleLocaleDataUpdate(path);
|
|
|
|
|
}
|
|
|
|
|
dataMap.remove(path);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
//数据库有记录但md5值改变或数据库版本需要更新则update
|
|
|
|
|
this->handleDBItemUpdate(path);
|
|
|
|
|
dataMap.remove(path);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//数据库中没有记录则insert
|
|
|
|
|
this->handleDBItemInsert(path);
|
|
|
|
|
dataMap.remove(path);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//数据库为空则全部insert
|
|
|
|
|
this->handleDBItemInsert(path);
|
|
|
|
|
dataMap.remove(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//遍历完成后重置标志位
|
|
|
|
|
m_localeChanged = false;
|
|
|
|
|
|
|
|
|
|
//数据库冗余项直接delete
|
|
|
|
|
if (!dataMap.isEmpty()) {
|
|
|
|
|
for (auto i = dataMap.constBegin(); i != dataMap.constEnd(); i++) {
|
|
|
|
|
this->handleDBItemDelete(i.key());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 13:45:05 +08:00
|
|
|
|
bool AppDBManager::handleValueSet(const ApplicationInfoMap appInfoMap)
|
|
|
|
|
{
|
|
|
|
|
bool res(true);
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
|
|
|
|
|
for (auto iter = appInfoMap.constBegin(); iter != appInfoMap.constEnd(); iter++) {
|
|
|
|
|
QString desktopFilePath = iter.key();
|
|
|
|
|
ApplicationPropertyMap propMap = iter.value();
|
|
|
|
|
for (auto propIter = propMap.constBegin(); propIter != propMap.constEnd(); ++propIter) {
|
|
|
|
|
QString field = ApplicationPropertyHelper(propIter.key()).dataBaseField();
|
|
|
|
|
|
|
|
|
|
query.prepare(QString("UPDATE appInfo SET MODIFYED_TIME='%0', %1=:value WHERE DESKTOP_FILE_PATH=:desktopFilePath")
|
|
|
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
|
|
|
|
.arg(field));
|
|
|
|
|
query.bindValue(":value", propIter.value());
|
|
|
|
|
query.bindValue(":desktopFilePath", desktopFilePath);
|
|
|
|
|
|
|
|
|
|
if (!this->startTransaction()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!query.exec()) {
|
|
|
|
|
qWarning() << "Set state failed!" << query.lastError();
|
|
|
|
|
res = false;
|
|
|
|
|
m_database.rollback();
|
|
|
|
|
} else {
|
|
|
|
|
if (this->startCommit()) {
|
|
|
|
|
ApplicationInfoMap infos2BSend;
|
|
|
|
|
infos2BSend[desktopFilePath].insert(propIter.key(), propIter.value());
|
|
|
|
|
Q_EMIT this->appDBItemUpdate(infos2BSend);
|
|
|
|
|
qDebug() << "app database update " << desktopFilePath << field << propIter.value() << "success!";
|
|
|
|
|
} else {
|
|
|
|
|
res = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-17 16:14:44 +08:00
|
|
|
|
QString AppDBManager::tranPidToDesktopFp(uint pid)
|
2023-02-17 15:55:10 +08:00
|
|
|
|
{
|
2023-08-08 16:54:07 +08:00
|
|
|
|
QFile file("/proc/" + QString::number(pid) + "/cmdline");
|
|
|
|
|
file.open(QFile::ReadOnly);
|
|
|
|
|
QList<QByteArray> cmdlist = file.readAll().split('\0');
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
cmdlist.removeAll("");
|
|
|
|
|
QString exePath;
|
|
|
|
|
for (int i = cmdlist.size() - 1; i >= 0; i--) {
|
|
|
|
|
if (cmdlist.at(i).startsWith("-") || cmdlist.at(i).contains("%")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-08-23 15:35:27 +08:00
|
|
|
|
if (!QUrl(cmdlist.at(i)).isRelative()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-08-08 16:54:07 +08:00
|
|
|
|
exePath = cmdlist.at(i);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-08-23 15:35:27 +08:00
|
|
|
|
|
2023-04-17 16:14:44 +08:00
|
|
|
|
QString desktopFilePath;
|
2023-08-23 15:35:27 +08:00
|
|
|
|
if (exePath.isEmpty()) {
|
|
|
|
|
qWarning() << "Can not find the desktop file by pid:" << pid << "because of empty exePath.";
|
|
|
|
|
return desktopFilePath;
|
|
|
|
|
}
|
2023-02-17 15:55:10 +08:00
|
|
|
|
|
2023-08-08 16:54:07 +08:00
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
query.prepare("SELECT DESKTOP_FILE_PATH, EXEC FROM APPINFO WHERE EXEC LIKE :exePath");
|
|
|
|
|
query.bindValue(":exePath", "%" + exePath.section('/', -1) + "%");
|
2023-02-17 15:55:10 +08:00
|
|
|
|
|
2023-08-08 16:54:07 +08:00
|
|
|
|
if (query.exec()) {
|
2023-02-17 15:55:10 +08:00
|
|
|
|
QMap<QString, QString> execInfos;
|
2023-08-08 16:54:07 +08:00
|
|
|
|
while (query.next()) {
|
|
|
|
|
execInfos[query.value("DESKTOP_FILE_PATH").toString()] = query.value("EXEC").toString();
|
|
|
|
|
desktopFilePath = query.value("DESKTOP_FILE_PATH").toString();
|
2023-02-17 15:55:10 +08:00
|
|
|
|
}
|
|
|
|
|
//筛选后有多个结果时进一步过滤
|
|
|
|
|
if (execInfos.size() > 1) {
|
2023-04-17 16:14:44 +08:00
|
|
|
|
desktopFilePath.clear();
|
|
|
|
|
for (auto it = execInfos.constBegin(); it != execInfos.constEnd(); it++) {
|
|
|
|
|
if (it.key().startsWith(AUTOSTART_APP_DESKTOP_PATH + "/")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
QStringList execlist = it.value().split(" ", QString::SkipEmptyParts);
|
2023-02-17 15:55:10 +08:00
|
|
|
|
for (QString &partOfExec : execlist) {
|
|
|
|
|
//remove the cmd option
|
|
|
|
|
if (partOfExec.contains("%")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
//remove the " in cmd
|
|
|
|
|
if (partOfExec.contains("\"")) {
|
|
|
|
|
partOfExec.remove("\"");
|
|
|
|
|
}
|
|
|
|
|
//compare the binary path
|
2023-08-08 16:54:07 +08:00
|
|
|
|
if (partOfExec.contains("/") && exePath.contains("/")) {
|
|
|
|
|
if (partOfExec == exePath) {
|
|
|
|
|
desktopFilePath = it.key();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ((partOfExec == exePath.section("/", -1)) || (partOfExec.section("/", -1) == exePath)) {
|
|
|
|
|
desktopFilePath = it.key();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-02-17 15:55:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-17 16:14:44 +08:00
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
2023-02-17 15:55:10 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-17 16:14:44 +08:00
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
|
|
|
|
qDebug() << "PID: " << pid << "Desktop file path: " << desktopFilePath;
|
2023-02-17 15:55:10 +08:00
|
|
|
|
} else {
|
2023-03-10 17:47:04 +08:00
|
|
|
|
qWarning() << "Can not find the desktop file of" << exePath << "by pid:" << pid;
|
2023-02-17 15:55:10 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-08-08 16:54:07 +08:00
|
|
|
|
qWarning() << "Fail to exec cmd" << query.lastQuery() << m_database.lastError();
|
2023-02-17 15:55:10 +08:00
|
|
|
|
}
|
2023-04-17 16:14:44 +08:00
|
|
|
|
return desktopFilePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString AppDBManager::desktopFilePathFromName(const QString &desktopFileName)
|
|
|
|
|
{
|
|
|
|
|
QString desktopFilePath;
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
query.prepare("SELECT DESKTOP_FILE_PATH FROM APPINFO WHERE DESKTOP_FILE_PATH LIKE :desktopFilePath");
|
|
|
|
|
query.bindValue(":desktopFilePath", "%/" + desktopFileName + ".desktop");
|
|
|
|
|
|
|
|
|
|
if (query.exec()) {
|
|
|
|
|
QStringList results;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
desktopFilePath = query.value("DESKTOP_FILE_PATH").toString();
|
|
|
|
|
results.append(desktopFilePath);
|
|
|
|
|
}
|
|
|
|
|
//筛选后有多个结果时进一步过滤
|
|
|
|
|
if (results.size() > 1) {
|
|
|
|
|
desktopFilePath.clear();
|
|
|
|
|
for (const QString &path : results) {
|
|
|
|
|
if (path.startsWith(AUTOSTART_APP_DESKTOP_PATH + "/")) {
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
desktopFilePath = path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
|
|
|
|
qDebug() << "Desktop file path is" << desktopFilePath;
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << "Can not find the desktop file by Name:" << desktopFileName;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << "Fail to exec cmd" << query.lastQuery();
|
|
|
|
|
}
|
|
|
|
|
return desktopFilePath;
|
2023-02-17 15:55:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-08 17:00:31 +08:00
|
|
|
|
QString AppDBManager::tranWinIdToDesktopFilePath(const QDBusVariant &id)
|
|
|
|
|
{
|
|
|
|
|
KWindowInfo info(id.variant().toULongLong(), NET::Properties(), NET::WM2AllProperties);
|
|
|
|
|
QString desktopFilePath;
|
|
|
|
|
if (info.valid()) {
|
2023-08-23 15:35:27 +08:00
|
|
|
|
QString classClass = info.windowClassClass(); //the 2nd part of WM_CLASS, specified by the application writer
|
|
|
|
|
QSqlQuery query(m_database);
|
|
|
|
|
query.setForwardOnly(true);
|
|
|
|
|
query.prepare("SELECT DESKTOP_FILE_PATH, START_UP_WMCLASS FROM APPINFO WHERE EXEC LIKE :classClass OR DESKTOP_FILE_PATH LIKE :classClass "
|
|
|
|
|
"OR LOWER(START_UP_WMCLASS)=:windowClassClass OR LOWER(LOCAL_NAME)=:windowClassClass");
|
|
|
|
|
query.bindValue(":classClass", "%" + classClass + "%");
|
|
|
|
|
query.bindValue(":windowClassClass", classClass.toLower());
|
2023-08-08 17:00:31 +08:00
|
|
|
|
|
2023-08-23 15:35:27 +08:00
|
|
|
|
if (query.exec()) {
|
|
|
|
|
QMap<QString, QString> wmClassInfos;
|
|
|
|
|
while (query.next()) {
|
|
|
|
|
wmClassInfos[query.value("DESKTOP_FILE_PATH").toString()] = query.value("START_UP_WMCLASS").toString();
|
|
|
|
|
desktopFilePath = query.value("DESKTOP_FILE_PATH").toString();
|
|
|
|
|
}
|
|
|
|
|
//筛选后有多个结果时进一步过滤
|
|
|
|
|
if (wmClassInfos.size() > 1) {
|
|
|
|
|
desktopFilePath.clear();
|
|
|
|
|
for (auto it = wmClassInfos.constBegin(); it != wmClassInfos.constEnd(); it++) {
|
|
|
|
|
if (it.key().startsWith(AUTOSTART_APP_DESKTOP_PATH)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (it.key().section("/", -1) == (classClass + ".desktop") || it.value().toLower() == classClass.toLower()) {
|
|
|
|
|
desktopFilePath = it.key();
|
|
|
|
|
break;
|
2023-08-08 17:00:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-23 15:35:27 +08:00
|
|
|
|
}
|
2023-08-08 17:00:31 +08:00
|
|
|
|
|
2023-08-23 15:35:27 +08:00
|
|
|
|
if (!desktopFilePath.isEmpty()) {
|
|
|
|
|
qDebug() << "WId:" << id.variant() << "Classclass of window:" << classClass << "Desktop file path:" << desktopFilePath;
|
2023-08-08 17:00:31 +08:00
|
|
|
|
} else {
|
2023-08-23 15:35:27 +08:00
|
|
|
|
qWarning() << "Can not find the desktop file by windowClassClass:" << classClass;
|
2023-08-08 17:00:31 +08:00
|
|
|
|
}
|
2023-08-23 15:35:27 +08:00
|
|
|
|
} else {
|
|
|
|
|
qWarning() << "Fail to exec cmd" << query.lastQuery();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (desktopFilePath.isEmpty()) {
|
|
|
|
|
desktopFilePath = this->tranPidToDesktopFp(info.pid());
|
2023-08-08 17:00:31 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << "Cannot find desktop flie by WinId:" << id.variant() << "it is invalid" << id.variant().toULongLong();
|
|
|
|
|
}
|
|
|
|
|
return desktopFilePath;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-12 11:26:03 +08:00
|
|
|
|
void AppDBManager::insertDBItem(const QString &desktopfd)
|
|
|
|
|
{
|
|
|
|
|
PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Insert);
|
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDBManager::updateDBItem(const QString &desktopfd)
|
|
|
|
|
{
|
|
|
|
|
PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::UpdateAll);
|
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDBManager::deleteDBItem(const QString &desktopfd)
|
|
|
|
|
{
|
|
|
|
|
PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Delete);
|
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
void AppDBManager::updateLocaleData(const QString &desktopFilePath)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-10 17:47:04 +08:00
|
|
|
|
PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateLocaleData);
|
2022-07-12 11:26:03 +08:00
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 17:47:04 +08:00
|
|
|
|
void AppDBManager::updateLaunchTimes(const QString &desktopFilePath)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-10 17:47:04 +08:00
|
|
|
|
PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateLaunchTimes);
|
2022-07-14 19:01:56 +08:00
|
|
|
|
item.setLaunchWillAdd(true);
|
|
|
|
|
item.setLaunchTimes(1);
|
2022-07-12 11:26:03 +08:00
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
void AppDBManager::updateFavoritesState(const QString &desktopFilePath, uint num)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-10 17:47:04 +08:00
|
|
|
|
PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateFavorites);
|
2022-07-14 19:01:56 +08:00
|
|
|
|
item.setFavorites(num);
|
2022-07-12 11:26:03 +08:00
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 17:24:06 +08:00
|
|
|
|
void AppDBManager::updateTopState(const QString &desktopFilePath, uint num)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-03-10 17:47:04 +08:00
|
|
|
|
PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateTop);
|
2022-07-12 11:26:03 +08:00
|
|
|
|
item.setTop(num);
|
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 13:45:05 +08:00
|
|
|
|
void AppDBManager::setValue(const ApplicationInfoMap &infos2BSet)
|
2022-07-12 11:26:03 +08:00
|
|
|
|
{
|
2023-04-14 13:45:05 +08:00
|
|
|
|
for (const QString &desktopFilePath : infos2BSet.keys()) {
|
|
|
|
|
PendingAppInfo item(desktopFilePath, PendingAppInfo::SetValue);
|
|
|
|
|
item.setValue(infos2BSet);
|
|
|
|
|
PendingAppInfoQueue::getAppInfoQueue().enqueue(item);
|
|
|
|
|
}
|
2022-07-12 11:26:03 +08:00
|
|
|
|
}
|