diff --git a/libsearch/app-db-common.h b/libsearch/app-db-common.h deleted file mode 100644 index 00a1ee0..0000000 --- a/libsearch/app-db-common.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef APPDBCOMMON_H -#define APPDBCOMMON_H - -#include - -namespace UkuiSearch { - -#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/" -#define APP_DATABASE_NAME "app-info.db" - -struct AppInfoResult -{ -public: - QString desktopPath; - QString iconName; - QString appLocalName; - QString firstLetter; - QString category; - int top; - int favorite; - int launchTimes; - int lock; - - AppInfoResult() : top(0), favorite(0), launchTimes(0), lock(0) {} -}; -} - -Q_DECLARE_METATYPE(UkuiSearch::AppInfoResult) - -#endif // APPDBCOMMON_H diff --git a/libsearch/app-info-dbus-argument.h b/libsearch/app-info-dbus-argument.h deleted file mode 100644 index 161e5d7..0000000 --- a/libsearch/app-info-dbus-argument.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef APPINFODBUSARGUMENT_H -#define APPINFODBUSARGUMENT_H - -#include -#include "app-db-common.h" - -namespace UkuiSearch { - - QDBusArgument &operator << (QDBusArgument &argument, const AppInfoResult &infoResult) - { - argument.beginStructure(); - argument << infoResult.desktopPath << infoResult.iconName << infoResult.appLocalName << infoResult.firstLetter - << infoResult.category << infoResult.top << infoResult.favorite << infoResult.launchTimes << infoResult.lock; - argument.endStructure(); - return argument; - } - - const QDBusArgument &operator >> (const QDBusArgument &argument, AppInfoResult &infoResult) - { - argument.beginStructure(); - argument >> infoResult.desktopPath >> infoResult.iconName >> infoResult.appLocalName >> infoResult.firstLetter - >> infoResult.category >> infoResult.top >> infoResult.favorite >> infoResult.launchTimes >> infoResult.lock; - - argument.endStructure(); - return argument; - } - -} - - -#endif // APPINFODBUSARGUMENT_H diff --git a/libsearch/appdata/app-info-dbus-argument.h b/libsearch/appdata/app-info-dbus-argument.h new file mode 100644 index 0000000..96bb4b8 --- /dev/null +++ b/libsearch/appdata/app-info-dbus-argument.h @@ -0,0 +1,82 @@ +#ifndef APPINFODBUSARGUMENT_H +#define APPINFODBUSARGUMENT_H + +#include +#include "application-property.h" + +namespace UkuiSearch { + + QDBusArgument &operator << (QDBusArgument &argument, const ApplicationProperty::Property &property) { + argument.beginStructure(); + argument << static_cast(property); + argument.endStructure(); + return argument; + } + + const QDBusArgument &operator >> (const QDBusArgument &argument, ApplicationProperty::Property &property) { + int value; + argument.beginStructure(); + argument >> value; + argument.endStructure(); + property = static_cast(value); + return argument; + } + + QDBusArgument &operator << (QDBusArgument &argument, const PropertyMap &appPropertyInfo) + { + argument.beginMap(/*qMetaTypeId()*/QVariant::Int, qMetaTypeId()); + for (auto i = appPropertyInfo.constBegin(); i != appPropertyInfo.constEnd(); ++i) { + QDBusVariant dbusVariant(i.value()); + argument.beginMapEntry(); + argument << static_cast(i.key()) << dbusVariant; + argument.endMapEntry(); + } + argument.endMap(); + return argument; + } + + const QDBusArgument &operator >> (const QDBusArgument &argument, PropertyMap &appPropertyInfo) + { + argument.beginMap(); + while (!argument.atEnd()) { + int key; + QVariant value; + argument.beginMapEntry(); + argument >> key >> value; + argument.endMapEntry(); + appPropertyInfo.insert(static_cast(key), value); + } + argument.endMap(); + return argument; + } + + QDBusArgument &operator << (QDBusArgument &argument, const ApplicationInfoMap &appInfo) + { + argument.beginMap(QVariant::String, qMetaTypeId()); + for (auto i = appInfo.constBegin(); i != appInfo.constEnd(); ++i) { + argument.beginMapEntry(); + argument << i.key() << i.value(); + argument.endMapEntry(); + } + argument.endMap(); + return argument; + } + + const QDBusArgument &operator >> (const QDBusArgument &argument, ApplicationInfoMap &appInfo) + { + argument.beginMap(); + while (!argument.atEnd()) { + QString key; + PropertyMap value; + argument.beginMapEntry(); + argument >> key >> value; + argument.endMapEntry(); + appInfo.insert(key, value); + } + argument.endMap(); + return argument; + } +} + + +#endif // APPINFODBUSARGUMENT_H diff --git a/libsearch/appdata/appdata.pri b/libsearch/appdata/appdata.pri index 24aa27a..aa1c8cc 100644 --- a/libsearch/appdata/appdata.pri +++ b/libsearch/appdata/appdata.pri @@ -6,7 +6,8 @@ HEADERS += \ # $$PWD/application-info-storage.h \ $$PWD/application-info.h \ $$PWD/application-property-helper.h \ - $$PWD/application-property.h + $$PWD/application-property.h \ + $$PWD/app-info-dbus-argument.h SOURCES += \ $$PWD/app-info-table.cpp \ diff --git a/libsearch/appdata/application-property.h b/libsearch/appdata/application-property.h index f61a3a0..e6b4967 100644 --- a/libsearch/appdata/application-property.h +++ b/libsearch/appdata/application-property.h @@ -4,7 +4,9 @@ #include #include #include +#include namespace UkuiSearch { + namespace ApplicationProperty { /** * @brief 表示应用基础信息 @@ -39,5 +41,4 @@ typedef QMap PropertyMap; typedef QMap ApplicationInfoMap; // desktopFile->PropertyMap } Q_DECLARE_METATYPE(UkuiSearch::ApplicationProperty::Property) - #endif // APPLICATIONPROPERTY_H diff --git a/libsearch/libsearch.pro b/libsearch/libsearch.pro index 21396de..fe614fb 100644 --- a/libsearch/libsearch.pro +++ b/libsearch/libsearch.pro @@ -53,8 +53,6 @@ SOURCES += \ libsearch.cpp HEADERS += \ - app-db-common.h \ - app-info-dbus-argument.h \ common.h \ file-utils.h \ global-settings.h \ diff --git a/ukui-search-app-data-service/app-db-manager.cpp b/ukui-search-app-data-service/app-db-manager.cpp index dc48f67..09be3bb 100644 --- a/ukui-search-app-data-service/app-db-manager.cpp +++ b/ukui-search-app-data-service/app-db-manager.cpp @@ -10,6 +10,7 @@ #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" +#define AUTOSTART_APP_DESKTOP_PATH "/etc/xdg/autostart" #define LAST_LOCALE_NAME QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/last-locale-name.conf" #define LOCALE_NAME_VALUE "CurrentLocaleName" @@ -52,7 +53,7 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa QString dbVersion = m_dbVersionQsettings->value(APP_DATABASE_VERSION_VALUE).toString(); if (dbVersion.isEmpty()) { m_dbVersionNeedUpdate = true; - }else if (dbVersion != APP_DATABASE_VERSION) { + } else if (dbVersion != APP_DATABASE_VERSION) { if (dbVersion.toDouble() < APP_DATABASE_VERSION.toDouble()) { m_dbVersionNeedUpdate = true; } else { @@ -66,7 +67,10 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa } //初始化数据库 - refreshAllData2DB(); + QStringList appPaths; + appPaths << GENERAL_APP_DESKTOP_PATH << ANDROID_APP_DESKTOP_PATH + << SNAPD_APP_DESKTOP_PATH << AUTOSTART_APP_DESKTOP_PATH; + refreshAllData2DB(appPaths); if (m_dbVersionNeedUpdate) { m_dbVersionQsettings->beginGroup(APP_DATABASE_VERSION_VALUE); @@ -97,6 +101,8 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa 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 @@ -126,7 +132,15 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa }); connect(m_watcher, &FileSystemWatcher::created, this, [ = ] (const QString &desktopfp, bool isDir) { - //event is IN_CREATE or IN_MOVED_TO + //event is IN_CREATE + if (!isDir and desktopfp.endsWith(".desktop")) { + QStringList appPaths(desktopfp.left(desktopfp.lastIndexOf("/"))); + this->refreshAllData2DB(appPaths); + } + }); + + connect(m_watcher, &FileSystemWatcher::moveTo, this, [ = ] (const QString &desktopfp, bool isDir) { + //event is IN_MOVED_TO if (!isDir and desktopfp.endsWith(".desktop")) { this->insertDBItem(desktopfp); } @@ -266,7 +280,7 @@ void AppDBManager::buildAppInfoDB() QSqlQuery sql(m_database); 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)") // .arg("ID INT")//自增id - .arg("DESKTOP_FILE_PATH TEXT")//desktop文件路径 + .arg("DESKTOP_FILE_PATH TEXT PRIMARY KEY NOT NULL")//desktop文件路径 .arg("MODIFYED_TIME TEXT")//YYYYMMDDHHmmSS 修改日期 .arg("INSERT_TIME TEXT")//YYYYMMDDHHmmSS 插入日期 .arg("LOCAL_NAME TEXT")//本地名称,跟随系统语言 @@ -274,7 +288,7 @@ void AppDBManager::buildAppInfoDB() .arg("NAME_ZH TEXT")//应用中文名称 .arg("PINYIN_NAME TEXT")//中文拼音 .arg("FIRST_LETTER_OF_PINYIN TEXT")//中文拼音首字母 - .arg("FIRST_LETTER_ALL")//拼音和英文全拼 + .arg("FIRST_LETTER_ALL TEXT")//拼音和英文全拼 .arg("ICON TEXT")//图标名称(或路径) .arg("TYPE TEXT")//应用类型 .arg("CATEGORY TEXT")//应用分类 @@ -286,95 +300,13 @@ void AppDBManager::buildAppInfoDB() .arg("LAUNCHED INT")//应用安装后是否打开过0:未打开过;1:打开过 .arg("TOP INT")//置顶顺序 0:未置顶;>0的数字表示置顶顺序 .arg("LOCK INT")//应用是否锁定(管控),0未锁定,1锁定 - .arg("PRIMARY KEY (DESKTOP_FILE_PATH)"); - + .arg("DONT_DISPLAY INT");//应用隐藏(NoDisplay, NotShowIn或位于autostart) if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; return; } } -void AppDBManager::updateAppInfoDB() -{ - -} - -void AppDBManager::getFilePathList(QStringList &pathList) -{ -// for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { -// pathList.append(i.value().at(0)); -// } -} - -/** - * @brief AppMatch::getAllDesktopFilePath 遍历所有desktop文件 - * @param path 存放desktop文件夹 - */ -void AppDBManager::getAllDesktopFilePath(QString path) -{ - /* - QDir dir(path); - if(!dir.exists()) { - return; - } - dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); - dir.setSorting(QDir::DirsFirst); - QFileInfoList list = dir.entryInfoList(); - list.removeAll(QFileInfo("/usr/share/applications/screensavers")); - if(list.size() < 1) { - return; - } - XdgDesktopFile desktopfile; - int i = 0; - while(i < list.size()) { - QFileInfo fileInfo = list.at(i); - //如果是文件夹,递归 - bool isDir = fileInfo.isDir(); - if(isDir) { - getAllDesktopFilePath(fileInfo.filePath()); - qDebug() << fileInfo.filePath(); - ++i; - } else { - QString filePathStr = fileInfo.filePath(); - if(m_excludedDesktopfiles.contains(filePathStr)) { - ++i; - continue; - } - - //过滤后缀不是.desktop的文件 - if(!filePathStr.endsWith(".desktop")) { - ++i; - continue; - } - - desktopfile.load(filePathStr); - if(desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) { - ++i; - continue; - } - - QString name = desktopfile.localizedValue("Name").toString(); - if(name.isEmpty()) { - ++i; - qDebug() << filePathStr << "name!!"; - continue; - } - - QString icon = desktopfile.iconName(); - NameString appname; - QStringList appInfolist; - - appname.app_name = name; - appInfolist << filePathStr << icon; - appInfolist.append(desktopfile.value("Name").toString()); - appInfolist.append(desktopfile.value("Name[zh_CN]").toString()); - m_installAppMap.insert(appname, appInfolist); - ++i; - } - } - */ -} - void AppDBManager::loadDesktopFilePaths(QString path, QFileInfoList &infolist) { QDir dir(path); @@ -387,14 +319,15 @@ bool AppDBManager::addItem2BackIfNotExist(QString itemName, QString itemDataType { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT * FROM sqlite_master WHERE name = 'appInfo' AND sql like '% %1 %' ").arg(itemName); + sql.setForwardOnly(true); + QString cmd = QString("SELECT * FROM sqlite_master WHERE name = 'appInfo' AND sql like '%%1%' ").arg(itemName); if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; res = false; return res; } if (sql.next()) { - qDebug() << cmd << "is exist!"; + qDebug() << itemName << "is exist!"; return res; } @@ -411,6 +344,8 @@ bool AppDBManager::addItem2BackIfNotExist(QString itemName, QString itemDataType if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; res = false; + } else { + qDebug() << "Add item" << itemName << "successful."; } if (!res) { qDebug() << "Fail to addItem2Back :" << itemName; @@ -418,10 +353,18 @@ bool AppDBManager::addItem2BackIfNotExist(QString itemName, QString itemDataType return res; } -void AppDBManager::refreshAllData2DB() +void AppDBManager::refreshAllData2DB(const QStringList &appPaths) { + //版本号改变更新数据库字段 + if (m_dbVersionNeedUpdate) { + for (auto iter = m_namesOfAppinfoTable.constBegin(); iter!= m_namesOfAppinfoTable.constEnd(); iter++) { + this->addItem2BackIfNotExist(iter.key(), iter.value()); + } + } + bool firstExec = false; QSqlQuery sql(m_database); + sql.setForwardOnly(true); QString cmd = "SELECT DESKTOP_FILE_PATH,MD5 FROM APPINFO"; QMap dataMap; if (!sql.exec(cmd)) { @@ -437,9 +380,10 @@ void AppDBManager::refreshAllData2DB() //遍历desktop文件 QFileInfoList infos; - this->loadDesktopFilePaths(GENERAL_APP_DESKTOP_PATH, infos); - this->loadDesktopFilePaths(ANDROID_APP_DESKTOP_PATH, infos); - this->loadDesktopFilePaths(SNAPD_APP_DESKTOP_PATH, infos); + for (const QString &path : appPaths) { + this->loadDesktopFilePaths(path, infos); + } + if(infos.size() < 1) { return; } @@ -453,14 +397,14 @@ void AppDBManager::refreshAllData2DB() continue; } //排除非法路径(黑名单 + 非desktop文件) - if (m_excludedDesktopfiles.contains(path) or !path.endsWith(".desktop")) { + if (/*m_excludedDesktopfiles.contains(path) or */!path.endsWith(".desktop")) { continue; } desktopfile.load(path); //排除NoDisplay和NotShowIn字段,排除loaclized名字为空 - if (desktopfile.value("NoDisplay").toString().contains("true") or - desktopfile.value("NotShowIn").toString().contains("UKUI") or + if (/*desktopfile.value("NoDisplay").toString().contains("true") or*/ +// desktopfile.value("NotShowIn").toString().contains("UKUI") or desktopfile.localizedValue("Name").toString().isEmpty()) { continue; } @@ -505,11 +449,11 @@ void AppDBManager::refreshAllData2DB() } } -bool AppDBManager::handleLocaleDataUpdate(const QString &desktopfp) +bool AppDBManager::handleLocaleDataUpdate(const QString &desktopFilePath) { bool res(true); XdgDesktopFile desktopFile; - desktopFile.load(desktopfp); + desktopFile.load(desktopFilePath); QString localName = desktopFile.localizedValue("Name", "NULL").toString(); QString firstLetter2All = localName; @@ -519,27 +463,23 @@ bool AppDBManager::handleLocaleDataUpdate(const QString &desktopfp) QSqlQuery sql(m_database); - QString cmd = QString("UPDATE appInfo SET " - "LOCAL_NAME = '%0', FIRST_LETTER_ALL = '%1'" - "WHERE DESKTOP_FILE_PATH='%2'") - .arg(localName) - .arg(firstLetter2All) - .arg(desktopfp); + sql.prepare("UPDATE appInfo SET LOCAL_NAME=:localName, FIRST_LETTER_ALL=:firstOfLetter2All WHERE DESKTOP_FILE_PATH=:desktopFilePath"); + sql.bindValue(":localName", localName); + sql.bindValue(":firstOfLetter2All", firstLetter2All); + sql.bindValue(":desktopFilePath", desktopFilePath); - if (!sql.exec(cmd)) { - qWarning() << m_database.lastError() << cmd; + if (!sql.exec()) { + qWarning() << m_database.lastError() << sql.lastQuery(); res = false; } if (res) { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "Update the locale data of " << result.desktopPath; - Q_EMIT this->appDBItemUpdate(result); - } - - + 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 { - qDebug() << "Fail to update the locale data of " << desktopfp; + qDebug() << "Fail to update the locale data of " << desktopFilePath; } return res; } @@ -625,21 +565,12 @@ bool AppDBManager::startCommit() } } -void AppDBManager::getInstallAppMap(QMap &installAppMap) -{ -// QMutexLocker locker(&s_mutex); -// for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { -// installAppMap[i.key().app_name] = i.value(); -// } -// installAppMap.detach(); -} - -bool AppDBManager::handleDBItemInsert(const QString &desktopfd) +bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath) { bool res(true); QSqlQuery sql(m_database); XdgDesktopFile desktopfile; - desktopfile.load(desktopfd); + desktopfile.load(desktopFilePath); QString hanzi, pinyin, firstLetterOfPinyin; QString localName = desktopfile.localizedValue("Name", "NULL").toString(); QString firstLetter2All = localName; @@ -669,61 +600,68 @@ bool AppDBManager::handleDBItemInsert(const QString &desktopfd) } } - QString cmd = 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, " - "LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK) " - "VALUES('%1','%2','%3','%4','%5','%6','%7','%8','%9','%10','%11','%12','%13','%14','%15',%16,%17,%18,%19,%20)") - .arg(desktopfd) - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(localName) - .arg(desktopfile.value("Name").toString()) - .arg(hanzi) - .arg(pinyin) - .arg(firstLetterOfPinyin) - .arg(firstLetter2All) - .arg(desktopfile.value("Icon").toString()) - .arg(desktopfile.value("Type").toString()) - .arg(desktopfile.value("Categories").toString()) - .arg(desktopfile.value("Exec").toString()) - .arg(desktopfile.value("Comment").toString().replace("'", "''")) - .arg(getAppDesktopMd5(desktopfd)) - .arg(0) - .arg(0) - .arg(0) - .arg(0) - .arg(0); - if (!sql.exec(cmd)) { - qWarning() << m_database.lastError() << cmd; + int dontDisplay = 0; + if (desktopfile.value("NoDisplay").toString().contains("true") || + desktopfile.value("NotShowIn").toString().contains("UKUI") || + desktopFilePath.startsWith(AUTOSTART_APP_DESKTOP_PATH)) { + dontDisplay = 1; + } + + 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, " + "LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY) " + "VALUES(:desktopFilePath, '%0', '%1', :localName, :enName, :zhName, :pinyinName, :firstLetterOfPinyin, :firstLetter2All, " + ":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8)") + .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) + .arg(dontDisplay)); + 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()); + + if (!sql.exec()) { + qWarning() << m_database.lastError() << sql.lastQuery(); res = false; } if (res) { - AppInfoResult result; - result.desktopPath = desktopfd; - result.iconName = desktopfile.value("Icon").toString(); - result.appLocalName = localName; - result.firstLetter = firstLetter2All; - result.category = desktopfile.value("Categories").toString(); - Q_EMIT this->appDBItemAdd(result); - qDebug() << "app database add " << desktopfd << "success!"; + Q_EMIT this->appDBItemAdd(desktopFilePath); + qDebug() << "app database add " << desktopFilePath << "success!"; } else { - qDebug() << "app database add " << desktopfd << "failed!"; + qDebug() << "app database add " << desktopFilePath << "failed!"; } return res; } -bool AppDBManager::handleDBItemDelete(const QString &desktopfd) +bool AppDBManager::handleDBItemDelete(const QString &desktopFilePath) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES, TOP FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); + sql.setForwardOnly(true); + QString cmd = "SELECT FAVORITES, TOP FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath"; + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); //查询要删除信息的应用是否被收藏或顶置过 - if (!sql.exec(cmd)) { - qWarning() << m_database.lastError() << cmd; + if (!sql.exec()) { + qWarning() << m_database.lastError() << sql.lastQuery(); } else if (sql.next()) { int favorites = sql.value("FAVORITES").toInt(); int top = sql.value("TOP").toInt(); @@ -744,29 +682,33 @@ bool AppDBManager::handleDBItemDelete(const QString &desktopfd) } //执行删除操作 - cmd = QString("DELETE FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); - if (!sql.exec(cmd)) { + cmd = "DELETE FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath"; + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); + if (!sql.exec()) { qWarning() << m_database.lastError() << cmd; res = false; } if (res) { - Q_EMIT this->appDBItemDelete(desktopfd); - qDebug() << "app database delete " << desktopfd << "success!"; + Q_EMIT this->appDBItemDelete(desktopFilePath); + qDebug() << "app database delete " << desktopFilePath << "success!"; } else { - qDebug() << "app database delete " << desktopfd << "failed!"; + qDebug() << "app database delete " << desktopFilePath << "failed!"; } return res; } -bool AppDBManager::handleDBItemUpdate(const QString &desktopfp) +bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath) { bool res(true); + int dontDisplay = 0; XdgDesktopFile desktopfile; - desktopfile.load(desktopfp); - if (desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) { - qDebug() << "app" << desktopfp << "is changed, but NoDisplay or NotShowIn is working!"; - return this->handleDBItemDelete(desktopfp); + desktopfile.load(desktopFilePath); + if (desktopfile.value("NoDisplay").toString().contains("true") || + desktopfile.value("NotShowIn").toString().contains("UKUI") || + desktopFilePath.startsWith(AUTOSTART_APP_DESKTOP_PATH)) { + dontDisplay = 1; } QString hanzi, pinyin, firstLetterOfPinyin; QString localName = desktopfile.localizedValue("Name", "NULL").toString(); @@ -799,87 +741,89 @@ bool AppDBManager::handleDBItemUpdate(const QString &desktopfp) } QSqlQuery sql(m_database); - QString cmd = QString("UPDATE appInfo SET " - "MODIFYED_TIME='%0'," - "LOCAL_NAME='%1'," - "NAME_EN='%2'," - "NAME_ZH='%3'," - "PINYIN_NAME='%4'," - "FIRST_LETTER_OF_PINYIN='%5'," - "FIRST_LETTER_ALL='%6'," - "ICON='%7'," - "TYPE='%8'," - "CATEGORY='%9'," - "EXEC='%10'," - "COMMENT='%11'," - "MD5='%12' " - "WHERE DESKTOP_FILE_PATH='%13'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(localName) - .arg(desktopfile.value("Name").toString()) - .arg(hanzi) - .arg(pinyin) - .arg(firstLetterOfPinyin) - .arg(firstLetter2All) - .arg(desktopfile.value("Icon").toString()) - .arg(desktopfile.value("Type").toString()) - .arg(desktopfile.value("Categories").toString()) - .arg(desktopfile.value("Exec").toString()) - .arg(desktopfile.value("Comment").toString().replace("'", "''")) - .arg(getAppDesktopMd5(desktopfp)) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << m_database.lastError() << cmd; + 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," + "MD5='%1'," + "DONT_DISPLAY=%2 " + "WHERE DESKTOP_FILE_PATH=:desktopFilePath") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(getAppDesktopMd5(desktopFilePath)) + .arg(dontDisplay)); + 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()); + + if (!sql.exec()) { + qWarning() << m_database.lastError() << sql.lastQuery(); res = false; } if (res) { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "app database update " << result.desktopPath << "success!"; - Q_EMIT this->appDBItemUpdate(result); - } + Q_EMIT this->appDBItemUpdateAll(desktopFilePath); + qDebug() << "app database update all data of" << desktopFilePath << "success!"; } else { - qDebug() << "app database update " << desktopfp << "failed!"; + qDebug() << "app database update " << desktopFilePath << "failed!"; } return res; } -bool AppDBManager::handleLaunchTimesUpdate(const QString &desktopfp, int num) +bool AppDBManager::handleLaunchTimesUpdate(const QString &desktopFilePath, int num) { qDebug() << "launch times will add:" << num; bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCH_TIMES FROM APPINFO WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); - if (sql.exec(cmd)) { + sql.setForwardOnly(true); + sql.prepare("SELECT LAUNCH_TIMES FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath"); + sql.bindValue(":desktopFilePath", desktopFilePath); + if (sql.exec()) { if (sql.next()) { int launchTimes = sql.value(0).toInt() + num; - cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH='%3'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(launchTimes) - .arg(1) - .arg(desktopfp); - if (!sql.exec(cmd)) { + sql.prepare(QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH=:desktopFilePath") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(launchTimes) + .arg(1)); + sql.bindValue(":desktopFilePath", desktopFilePath); + if (!sql.exec()) { qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } else { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "app database update " << result.desktopPath << "launch times: " << result.launchTimes << "success!"; - Q_EMIT this->appDBItemUpdate(result); - } + 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 { - qWarning() << "Failed to exec next!" << cmd; + qWarning() << "Failed to exec next!" << sql.lastQuery(); res = false; } } else { - qWarning() << "Failed to exec:" << cmd; + qWarning() << "Failed to exec:" << sql.lastQuery(); res = false; } return res; } -bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopfp, int num, bool isOrderChanged) +bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopFilePath, int num, bool isOrderChanged) { if (num < 0) { qWarning() << "Invalid favorite num, I quit!!!"; @@ -888,6 +832,7 @@ bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopfp, int num, bool res(true); QSqlQuery sql(m_database); + sql.setForwardOnly(true); QString cmd; //当直接设置的时候需要查询要设置的favorites标志位是否被占用 @@ -899,11 +844,11 @@ bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopfp, int num, while (sql.next()) { if (num && sql.value("FAVORITES").toInt() == num) { res = false; - if (sql.value("DESKTOP_FILE_PATH").toString() == desktopfp) { + if (sql.value("DESKTOP_FILE_PATH").toString() == desktopFilePath) { qWarning() << "favorites state has no changes, I quit!"; return res; } else { - qWarning() << "the favorites num:" << num << "has been used, fail to update favorites state of" << desktopfp; + qWarning() << "the favorites num:" << num << "has been used, fail to update favorites state of" << desktopFilePath; return res; } } @@ -913,24 +858,24 @@ bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopfp, int num, //更新favorites状态 - cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH='%2'") + cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH=:desktopFilePath") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(num) - .arg(desktopfp); - if (!sql.exec(cmd)) { + .arg(num); + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); + if (!sql.exec()) { qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } else { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "app database update " << result.desktopPath << "favorites state: " << result.favorite << "success!"; - Q_EMIT this->appDBItemUpdate(result); - } + ApplicationInfoMap appInfo; + appInfo[desktopFilePath].insert(ApplicationProperty::Favorites, QVariant(num)); + Q_EMIT this->appDBItemUpdate(appInfo); + qDebug() << "app database update " << desktopFilePath << "favorites state: " << num << "success!"; } return res; } -bool AppDBManager::handleTopStateUpdate(const QString &desktopfp, int num, bool isOrderChanged) +bool AppDBManager::handleTopStateUpdate(const QString &desktopFilePath, int num, bool isOrderChanged) { if (num < 0) { qWarning() << "Invalid top num, I quit!!!"; @@ -939,6 +884,7 @@ bool AppDBManager::handleTopStateUpdate(const QString &desktopfp, int num, bool bool res(true); QSqlQuery sql(m_database); + sql.setForwardOnly(true); //当直接设置的时候需要查询要设置的top标志位是否被占用 QString cmd; @@ -950,11 +896,11 @@ bool AppDBManager::handleTopStateUpdate(const QString &desktopfp, int num, bool while (sql.next()) { if (num && sql.value("TOP").toInt() == num) { res = false; - if (sql.value("DESKTOP_FILE_PATH").toString() == desktopfp) { + if (sql.value("DESKTOP_FILE_PATH").toString() == desktopFilePath) { qWarning() << "top state has no changes, I quit!"; return res; } else { - qWarning() << "the top num:" << num << "has been used, fail to update top state of" << desktopfp; + qWarning() << "the top num:" << num << "has been used, fail to update top state of" << desktopFilePath; return res; } } @@ -963,68 +909,40 @@ bool AppDBManager::handleTopStateUpdate(const QString &desktopfp, int num, bool } //更新top状态 - cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") + cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH=:desktopFilePath") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(num) - .arg(desktopfp); - if (!sql.exec(cmd)) { + .arg(num); + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); + + if (!sql.exec()) { qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } else { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "app database update " << result.desktopPath << "top state: " << result.top << "success!"; - Q_EMIT this->appDBItemUpdate(result); - } + ApplicationInfoMap appInfo; + appInfo[desktopFilePath].insert(ApplicationProperty::Top, QVariant(num)); + Q_EMIT this->appDBItemUpdate(appInfo); + qDebug() << "app database update " << desktopFilePath << "top state: " << num << "success!"; } return res; } -bool AppDBManager::handleLockStateUpdate(const QString &desktopfp, int num) +bool AppDBManager::handleLockStateUpdate(const QString &desktopFilePath, int num) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LOCK=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(num) - .arg(desktopfp); - if (!sql.exec(cmd)) { + 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()) { qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } else { - AppInfoResult result; - if (this->createAppInfoResult(desktopfp, result)) { - qDebug() << "app database update " << result.desktopPath << "lock state: " << result.lock << "success!"; - Q_EMIT this->appDBItemUpdate(result); - } - } - return res; -} - -bool AppDBManager::createAppInfoResult(const QString &desktopfp, AppInfoResult &result) -{ - bool res(false); - QSqlQuery sql(m_database); - QString cmd = QString("SELECT ICON, LOCAL_NAME, FIRST_LETTER_ALL, CATEGORY, " - "TOP, FAVORITES, LAUNCH_TIMES, LOCK FROM APPINFO " - "WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); - if(sql.exec(cmd)) { - if (sql.next()) { - result.desktopPath = desktopfp; - result.iconName = sql.value(0).toString(); - result.appLocalName = sql.value(1).toString(); - result.firstLetter = sql.value(2).toString(); - result.category = sql.value(3).toString(); - result.top = sql.value(4).toInt(); - result.favorite = sql.value(5).toInt(); - result.launchTimes = sql.value(6).toInt(); - result.lock = sql.value(7).toInt(); - res = true; - } else { - qWarning() << "Fail to exec next. " << cmd << m_database.lastError(); - } - } else { - qWarning() << "Fail to exec " << cmd << m_database.lastError(); + ApplicationInfoMap appInfo; + appInfo[desktopFilePath].insert(ApplicationProperty::Lock, QVariant(num)); + Q_EMIT this->appDBItemUpdate(appInfo); + qDebug() << "app database update " << desktopFilePath << "lock state: " << num << "success!"; } return res; } @@ -1035,10 +953,11 @@ QString AppDBManager::tranPidToDesktopFp(int pid) QString desktopfp; QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH, EXEC FROM APPINFO WHERE EXEC LIKE '%%0%'") - .arg(exePath.section('/', -1)); + sql.setForwardOnly(true); + sql.prepare("SELECT DESKTOP_FILE_PATH, EXEC FROM APPINFO WHERE EXEC LIKE :exePath AND DONT_DISPLAY = 0"); + sql.bindValue(":exePath", "%" + exePath.section('/', -1) + "%"); - if (sql.exec(cmd)) { + if (sql.exec()) { QMap execInfos; while (sql.next()) { execInfos[sql.value("DESKTOP_FILE_PATH").toString()] = sql.value("EXEC").toString(); @@ -1061,7 +980,7 @@ QString AppDBManager::tranPidToDesktopFp(int pid) //compare the binary path if ((partOfExec.contains("/") && partOfExec == exePath) || (partOfExec == exePath.section("/", -1))) { - desktopfp = path; + desktopfp = execInfos.key(path); break; } } @@ -1074,10 +993,10 @@ QString AppDBManager::tranPidToDesktopFp(int pid) if (!desktopfp.isEmpty()) { qDebug() << "PID: " << pid << "Desktop file path: " << desktopfp; } else { - qWarning() << "The desktop file can not be found by pid: " << pid; + qWarning() << "Can not find the desktop file of" << exePath << "by pid:" << pid; } } else { - qWarning() << "Fail to exec cmd" << cmd << m_database.lastError(); + qWarning() << "Fail to exec cmd" << sql.lastQuery() << m_database.lastError(); } return desktopfp; } @@ -1100,44 +1019,44 @@ void AppDBManager::deleteDBItem(const QString &desktopfd) PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -void AppDBManager::updateLocaleData(const QString &desktopfp) +void AppDBManager::updateLocaleData(const QString &desktopFilePath) { - PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateLocaleData); + PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateLocaleData); PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -void AppDBManager::updateLaunchTimes(const QString &desktopfp) +void AppDBManager::updateLaunchTimes(const QString &desktopFilePath) { - PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateLaunchTimes); + PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateLaunchTimes); item.setLaunchWillAdd(true); item.setLaunchTimes(1); PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -void AppDBManager::updateFavoritesState(const QString &desktopfp, int num, bool isOrderChanged) +void AppDBManager::updateFavoritesState(const QString &desktopFilePath, int num, bool isOrderChanged) { - PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateFavorites); + PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateFavorites); item.setFavorites(num); item.setChangeFavoritePos(isOrderChanged); PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -void AppDBManager::updateTopState(const QString &desktopfp, int num, bool isOrderChanged) +void AppDBManager::updateTopState(const QString &desktopFilePath, int num, bool isOrderChanged) { - PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateTop); + PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateTop); item.setTop(num); item.setChangeTopPos(isOrderChanged); PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -void AppDBManager::udpateLockState(const QString &desktopfp, int num) +void AppDBManager::udpateLockState(const QString &desktopFilePath, int num) { - PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateTop); + PendingAppInfo item(desktopFilePath, PendingAppInfo::HandleType::UpdateTop); item.setLock(num); PendingAppInfoQueue::getAppInfoQueue().enqueue(item); } -bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) +bool AppDBManager::changeFavoriteAppPos(const QString &desktopFilePath, int pos) { if (pos < 1) { qWarning() << "To be moved to a invalid favorites pos , I quit!!"; @@ -1146,11 +1065,14 @@ bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfp); + sql.setForwardOnly(true); + QString cmd = "SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath"; + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); int previousPos = 0; //记录应用原位置 - if (!sql.exec(cmd)) { + if (!sql.exec()) { qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; res = false; } else { @@ -1158,7 +1080,7 @@ bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) previousPos = sql.value(0).toInt(); if (previousPos < 1) { - qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopfp); + qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopFilePath); } if (previousPos == pos) { @@ -1181,7 +1103,7 @@ bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) } else { while (sql.next()) { if (sql.value("FAVORITES").toInt() == previousPos) { - this->updateFavoritesState(desktopfp, pos, true); + this->updateFavoritesState(desktopFilePath, pos, true); continue; } if (previousPos > pos) { @@ -1196,7 +1118,7 @@ bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) return res; } -bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) +bool AppDBManager::changeTopAppPos(const QString &desktopFilePath, int pos) { if (pos < 1) { qWarning() << "To be moved to a invalid top pos, I quit!!"; @@ -1205,11 +1127,13 @@ bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfp); + QString cmd = "SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFilePath"; + sql.prepare(cmd); + sql.bindValue(":desktopFilePath", desktopFilePath); int previousPos = 0; //记录应用原位置 - if (!sql.exec(cmd)) { + if (!sql.exec()) { qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; res = false; } else { @@ -1217,7 +1141,7 @@ bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) previousPos = sql.value(0).toInt(); if (previousPos < 1) { - qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopfp); + qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopFilePath); res = false; return res; } @@ -1243,7 +1167,7 @@ bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) } else { while (sql.next()) { if (sql.value("TOP").toInt() == previousPos) { - this->updateTopState(desktopfp, pos, true); + this->updateTopState(desktopFilePath, pos, true); continue; } if (previousPos > pos) { @@ -1257,130 +1181,3 @@ bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) return res; } - -QVector AppDBManager::getAppInfoResults() -{ - QVector appInfoResults; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,CATEGORY,TOP,FAVORITES,LAUNCH_TIMES,LOCK,FIRST_LETTER_ALL FROM APPINFO"); - - if (sql.exec(cmd)) { - while (sql.next()) { - AppInfoResult result; - result.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); - result.appLocalName = sql.value("LOCAL_NAME").toString(); - result.iconName = sql.value("ICON").toString(); - result.category = sql.value("CATEGORY").toString(); - result.top = sql.value("TOP").toInt(); - result.favorite = sql.value("FAVORITES").toInt(); - result.launchTimes = sql.value("LAUNCH_TIMES").toInt(); - result.lock = sql.value("LOCK").toInt(); - result.firstLetter = sql.value("FIRST_LETTER_ALL").toString(); - appInfoResults.append(std::move(result)); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return appInfoResults; -} - -int AppDBManager::getAppLockState(const QString &desktopfp) -{ - int lockState = -1; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LOCK FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - - if (sql.exec(cmd)) { - if (sql.next()) { - lockState = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return lockState; -} - -int AppDBManager::getAppTopState(const QString &desktopfp) -{ - int topState = -1; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - - if (sql.exec(cmd)) { - if (sql.next()) { - topState = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return topState; -} - -int AppDBManager::getAppLaunchedState(const QString &desktopfp) -{ - int launchedState = -1; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCHED FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - - if (sql.exec(cmd)) { - if (sql.next()) { - launchedState = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return launchedState; -} - -int AppDBManager::getAppFavoriteState(const QString &desktopfp) -{ - int favoriteState = -1; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - - if (sql.exec(cmd)) { - if (sql.next()) { - favoriteState = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return favoriteState; -} - -QString AppDBManager::getAppCategory(const QString &desktopfp) -{ - QString category; - QSqlQuery sql(m_database); - QString cmd = QString("SELECT CATEGORY FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - - if (sql.exec(cmd)) { - if (sql.next()) { - category = sql.value(0).toString(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - } - - return category; -} diff --git a/ukui-search-app-data-service/app-db-manager.h b/ukui-search-app-data-service/app-db-manager.h index 058ca70..68e314b 100644 --- a/ukui-search-app-data-service/app-db-manager.h +++ b/ukui-search-app-data-service/app-db-manager.h @@ -11,12 +11,14 @@ #include #include #include -#include "app-db-common.h" #include "pending-app-info-queue.h" #include "file-system-watcher.h" +#include "application-property.h" +#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/" +#define APP_DATABASE_NAME "app-info.db" #define CONNECTION_NAME QLatin1String("ukss-appdb-connection") -static const QString APP_DATABASE_VERSION = QStringLiteral("1.0"); +static const QString APP_DATABASE_VERSION = QStringLiteral("1.1"); namespace UkuiSearch { /** @@ -24,18 +26,6 @@ namespace UkuiSearch { * 功能:1.遍历并且监听desktop文件目录,建立并且维护应用信息数据库。 * 2.监听应用安装,打开事件,收藏等事件,更新数据库 */ -class NameString { -public: - explicit NameString(const QString &str_) : app_name(str_) {} - NameString() = default; - QString app_name; - bool operator<(const NameString& name) const { - return this->app_name.length() <= name.app_name.length(); - } - bool operator==(const NameString& name) const { - return this->app_name == name.app_name; - } -}; class AppDBManager : public QThread { @@ -52,7 +42,7 @@ public: static AppDBManager *getInstance(); //刷新数据库数据 - void refreshAllData2DB(); + void refreshAllData2DB(const QStringList &appPaths); //获取desktop文件的md5值 QString getAppDesktopMd5(const QString &desktopfd); @@ -60,16 +50,15 @@ public: bool startTransaction(); bool startCommit(); - bool handleDBItemInsert(const QString &desktopfd); - bool handleDBItemUpdate(const QString &desktopfp); - bool handleDBItemDelete(const QString &desktopfd); + bool handleDBItemInsert(const QString &desktopFilePath); + bool handleDBItemUpdate(const QString &desktopFilePath); + bool handleDBItemDelete(const QString &desktopFilePath); - bool handleLocaleDataUpdate(const QString &desktopfp); - bool handleLaunchTimesUpdate(const QString &desktopfp, int num); - bool handleFavoritesStateUpdate(const QString &desktopfp, int num, bool isOrderChanged = false); - bool handleTopStateUpdate(const QString &desktopfp, int num, bool isOrderChanged = false); - bool handleLockStateUpdate(const QString &desktopfp, int num); - bool createAppInfoResult(const QString &desktopfp, AppInfoResult &result); + bool handleLocaleDataUpdate(const QString &desktopFilePath); + bool handleLaunchTimesUpdate(const QString &desktopFilePath, int num); + bool handleFavoritesStateUpdate(const QString &desktopFilePath, int num, bool isOrderChanged = false); + bool handleTopStateUpdate(const QString &desktopFilePath, int num, bool isOrderChanged = false); + bool handleLockStateUpdate(const QString &desktopFilePath, int num); public Q_SLOTS: //通过pid查找对应的desktop文件 @@ -81,25 +70,15 @@ public Q_SLOTS: void deleteDBItem(const QString &desktopfd); //对数据库某字段进行update - void updateLocaleData(const QString &desktopfp); - void updateLaunchTimes(const QString &desktopfp); - void updateFavoritesState(const QString &desktopfp, int num, bool isOrderChanged = false); - void updateTopState(const QString &desktopfp, int num, bool isOrderChanged = false); - void udpateLockState(const QString &desktopfp, int num); + void updateLocaleData(const QString &desktopFilePath); + void updateLaunchTimes(const QString &desktopFilePath); + void updateFavoritesState(const QString &desktopFilePath, int num, bool isOrderChanged = false); + void updateTopState(const QString &desktopFilePath, int num, bool isOrderChanged = false); + void udpateLockState(const QString &desktopFilePath, int num); //拖动改变置顶和收藏应用位置 - bool changeFavoriteAppPos(const QString &desktopfp, int pos); - bool changeTopAppPos(const QString &desktopfp, int pos); - - //获取数据库中全部信息 - QVector getAppInfoResults(); - - //查询某应用的某个字段的值 - int getAppLockState(const QString &desktopfp); - int getAppTopState(const QString &desktopfp); - int getAppLaunchedState(const QString &desktopfp); - int getAppFavoriteState(const QString &desktopfp); - QString getAppCategory(const QString &desktopfp); + bool changeFavoriteAppPos(const QString &desktopFilePath, int pos); + bool changeTopAppPos(const QString &desktopFilePath, int pos); protected: void run() override; @@ -114,7 +93,6 @@ private: //数据库查找指定字段不存在则添加到最后并设置初始值 bool addItem2BackIfNotExist(QString itemName, QString itemDataType, QVariant defult = QVariant()); - //链接数据库 bool openDataBase(); //刷新数据库 @@ -125,12 +103,6 @@ private: //创建数据库字段 void buildAppInfoDB(); - //暂时弃用 - void updateAppInfoDB(); - void getAllDesktopFilePath(QString path); - void getFilePathList(QStringList &pathList); - void getInstallAppMap(QMap &installAppMap); - private: static QMutex s_mutex; bool m_localeChanged; @@ -150,6 +122,31 @@ private: QString m_snapdPath; FileSystemWatcher *m_snapdWatcher = nullptr; + //数据库当前所有字段 + QMap m_namesOfAppinfoTable = { + {"DESKTOP_FILE_PATH", "TEXT"}, + {"MODIFYED_TIME", "TEXT"}, + {"INSERT_TIME","TEXT"}, + {"LOCAL_NAME", "TEXT"}, + {"NAME_EN", "TEXT"}, + {"NAME_ZH", "TEXT"}, + {"PINYIN_NAME", "TEXT"}, + {"FIRST_LETTER_OF_PINYIN", "TEXT"}, + {"FIRST_LETTER_ALL", "TEXT"}, + {"ICON", "TEXT"}, + {"TYPE", "TEXT"}, + {"CATEGORY", "TEXT"}, + {"EXEC", "TEXT"}, + {"COMMENT", "TEXT"}, + {"MD5", "TEXT"}, + {"LAUNCH_TIMES", "INT"}, + {"FAVORITES", "INT"}, + {"LAUNCHED", "INT"}, + {"TOP", "INT"}, + {"LOCK", "INT"}, + {"DONT_DISPLAY", "INT"} + }; + //应用黑名单 QStringList m_excludedDesktopfiles = { "/usr/share/applications/software-properties-livepatch.desktop", @@ -199,13 +196,11 @@ private: "/usr/share/applications/screensavers" }; - //暂时弃用 - QMap m_installAppMap; - Q_SIGNALS: //操作数据库 - void appDBItemUpdate(const AppInfoResult&); - void appDBItemAdd(const AppInfoResult&); + void appDBItemUpdate(const ApplicationInfoMap&); + void appDBItemUpdateAll(const QString&); + void appDBItemAdd(const QString&); void appDBItemDelete(const QString&); void finishHandleAppDB(); diff --git a/ukui-search-app-data-service/signal-transformer.cpp b/ukui-search-app-data-service/signal-transformer.cpp index 97bdbf6..cb8d76c 100644 --- a/ukui-search-app-data-service/signal-transformer.cpp +++ b/ukui-search-app-data-service/signal-transformer.cpp @@ -8,22 +8,33 @@ SignalTransformer *SignalTransformer::getTransformer() return instance; } -void SignalTransformer::handleItemInsert(const AppInfoResult &item) +void SignalTransformer::handleItemInsert(const QString &desktopFilePath) { QMutexLocker locker(&s_mutex); - m_items2BInsert.append(item); + m_items2BInsert.append(desktopFilePath); } -void SignalTransformer::handleItemUpdate(const AppInfoResult &item) +void SignalTransformer::handleItemUpdate(const ApplicationInfoMap &item) { QMutexLocker locker(&s_mutex); - m_items2BUpdate.append(item); + for(auto it = item.constBegin(); it != item.constEnd(); it++) { + PropertyMap propertyinfo = it.value(); + for (auto i = propertyinfo.constBegin(); i != propertyinfo.constEnd(); i++) { + m_items2BUpdate[it.key()].insert(i.key(), i.value()); + } + } } -void SignalTransformer::handleItemDelete(const QString &desktopfp) +void SignalTransformer::handleItemUpdateAll(const QString &desktopFilePath) { QMutexLocker locker(&s_mutex); - m_items2BDelete.append(desktopfp); + m_items2BUpdateAll.append(desktopFilePath); +} + +void SignalTransformer::handleItemDelete(const QString &desktopFilePath) +{ + QMutexLocker locker(&s_mutex); + m_items2BDelete.append(desktopFilePath); } void SignalTransformer::handleSignalTransform() @@ -39,6 +50,11 @@ void SignalTransformer::handleSignalTransform() m_items2BUpdate.clear(); } + if (!m_items2BUpdateAll.isEmpty()) { + Q_EMIT this->appDBItemsUpdateAll(m_items2BUpdateAll); + m_items2BUpdateAll.clear(); + } + if (!m_items2BDelete.isEmpty()) { Q_EMIT this->appDBItemsDelete(m_items2BDelete); m_items2BDelete.clear(); @@ -50,6 +66,7 @@ SignalTransformer::SignalTransformer(QObject *parent) : QObject(parent) connect(AppDBManager::getInstance(), &AppDBManager::appDBItemAdd, this, &SignalTransformer::handleItemInsert); connect(AppDBManager::getInstance(), &AppDBManager::appDBItemUpdate, this, &SignalTransformer::handleItemUpdate); connect(AppDBManager::getInstance(), &AppDBManager::appDBItemDelete, this, &SignalTransformer::handleItemDelete); + connect(AppDBManager::getInstance(), &AppDBManager::appDBItemUpdateAll, this, &SignalTransformer::handleItemUpdateAll); connect(AppDBManager::getInstance(), &AppDBManager::finishHandleAppDB, this, &SignalTransformer::handleSignalTransform); } diff --git a/ukui-search-app-data-service/signal-transformer.h b/ukui-search-app-data-service/signal-transformer.h index 6bb4ef4..1cd793b 100644 --- a/ukui-search-app-data-service/signal-transformer.h +++ b/ukui-search-app-data-service/signal-transformer.h @@ -20,9 +20,10 @@ public: static QMutex s_mutex; public Q_SLOTS: - void handleItemInsert(const AppInfoResult &item); - void handleItemUpdate(const AppInfoResult &item); - void handleItemDelete(const QString &desktopfp); + void handleItemUpdate(const ApplicationInfoMap &item); + void handleItemUpdateAll(const QString &desktopFilePath); + void handleItemInsert(const QString &desktopFilePath); + void handleItemDelete(const QString &desktopFilePath); void handleSignalTransform(); private: @@ -30,14 +31,16 @@ private: SignalTransformer(const SignalTransformer &) = delete; SignalTransformer& operator = (const SignalTransformer&) = delete; - QVector m_items2BUpdate; - QVector m_items2BInsert; + ApplicationInfoMap m_items2BUpdate; + QStringList m_items2BUpdateAll; + QStringList m_items2BInsert; QStringList m_items2BDelete; Q_SIGNALS: - void appDBItemsUpdate(QVector); - void appDBItemsAdd(QVector); - void appDBItemsDelete(QStringList); + void appDBItemsUpdateAll(const QStringList&); + void appDBItemsUpdate(const ApplicationInfoMap&); + void appDBItemsAdd(const QStringList&); + void appDBItemsDelete(const QStringList&); }; #endif // SIGNALTRANSFORMER_H diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.cpp b/ukui-search-app-data-service/ukui-search-app-data-service.cpp index 592a1c8..ea22b2c 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.cpp +++ b/ukui-search-app-data-service/ukui-search-app-data-service.cpp @@ -20,11 +20,11 @@ UkuiSearchAppDataService::UkuiSearchAppDataService(int &argc, char *argv[], cons if (!this->isRunning()) { qDebug() << "First running, I'm in app-db manager dbus rigister."; - qRegisterMetaType("AppInfoResult"); - qRegisterMetaType>("QVector"); + qRegisterMetaType("PropertyMap"); + qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType>(); + qRegisterMetaType("ApplicationInfoMap"); + qDBusRegisterMetaType(); AppDBManager::getInstance(); diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.pro b/ukui-search-app-data-service/ukui-search-app-data-service.pro index 03ffc09..2645230 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.pro +++ b/ukui-search-app-data-service/ukui-search-app-data-service.pro @@ -59,5 +59,6 @@ DEPENDPATH += $$PWD/../libchinese-segmentation LIBS += -L$$OUT_PWD/../libsearch/ -lukui-search INCLUDEPATH += $$PWD/../libsearch \ - $$PWD/../libsearch/filesystemwatcher + $$PWD/../libsearch/filesystemwatcher \ + $$PWD/../libsearch/appdata DEPENDPATH += $$PWD/../libsearch