From 13288b97bb52335f44b1728af0270e4c4c891b80 Mon Sep 17 00:00:00 2001 From: JunjieBai Date: Tue, 28 Jun 2022 11:20:36 +0800 Subject: [PATCH 1/2] Add interfaces for changing position of top&favorites apps. Add appDB update signal. Add signal transformer and register its signals as dbus signals. --- libsearch/app-db-common.h | 51 +++ libsearch/appdata/app-info-table-private.h | 27 +- libsearch/appdata/app-info-table.cpp | 377 ++++++++++++------ libsearch/appdata/app-info-table.h | 99 +++-- libsearch/libsearch.pro | 1 + .../app-db-common-defines.h | 11 - .../app-db-manager.cpp | 49 ++- ukui-search-app-data-service/app-db-manager.h | 9 +- .../signal-transformer.cpp | 47 +++ .../signal-transformer.h | 43 ++ .../ukui-search-app-data-service.cpp | 24 +- .../ukui-search-app-data-service.pro | 3 +- 12 files changed, 557 insertions(+), 184 deletions(-) create mode 100644 libsearch/app-db-common.h delete mode 100644 ukui-search-app-data-service/app-db-common-defines.h create mode 100644 ukui-search-app-data-service/signal-transformer.cpp create mode 100644 ukui-search-app-data-service/signal-transformer.h diff --git a/libsearch/app-db-common.h b/libsearch/app-db-common.h new file mode 100644 index 0000000..c8ef2dd --- /dev/null +++ b/libsearch/app-db-common.h @@ -0,0 +1,51 @@ +#ifndef APPDBCOMMON_H +#define APPDBCOMMON_H + +#include +#include +#include + +namespace UkuiSearch { + +#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/" +#define APP_DATABASE_NAME "app-info.db" + +struct AppInfoResult +{ + QString desktopPath; + QString iconName; + QString appLocalName; + QString firstLetter; + QString category; + int top; + int favorate; + int launchTimes; + int lock; + + AppInfoResult() : top(0), favorate(0), launchTimes(0), lock(0) {} + friend QDBusArgument &operator << (QDBusArgument &argument, const AppInfoResult &infoResult) + { + argument.beginStructure(); + argument << infoResult.desktopPath << infoResult.iconName << infoResult.appLocalName << infoResult.firstLetter + << infoResult.category << infoResult.top << infoResult.favorate << infoResult.launchTimes << infoResult.lock; + argument.endStructure(); + return argument; + } + + friend const QDBusArgument &operator >> (const QDBusArgument &argument, AppInfoResult &infoResult) + { + argument.beginStructure(); + argument >> infoResult.desktopPath >> infoResult.iconName >> infoResult.appLocalName >> infoResult.firstLetter + >> infoResult.category >> infoResult.top >> infoResult.favorate >> infoResult.launchTimes >> infoResult.lock; + + argument.endStructure(); + return argument; + } + +}; + +} + +Q_DECLARE_METATYPE(UkuiSearch::AppInfoResult) + +#endif // APPDBCOMMON_H diff --git a/libsearch/appdata/app-info-table-private.h b/libsearch/appdata/app-info-table-private.h index 7cbe75d..c0ef60d 100644 --- a/libsearch/appdata/app-info-table-private.h +++ b/libsearch/appdata/app-info-table-private.h @@ -1,10 +1,13 @@ #ifndef APPINFOTABLEPRIVATE_H #define APPINFOTABLEPRIVATE_H + +#include "app-info-table.h" #include +#include #include -#include namespace UkuiSearch { + class AppInfoTablePrivate : public QObject { Q_OBJECT @@ -15,27 +18,36 @@ public: bool setAppFavoritesState(QString &desktopfp, size_t num); bool setAppTopState(QString &desktopfp, size_t num); + + //下面三个暂时未封装 bool setAppLaunchTimes(QString &desktopfp, size_t num); bool updateAppLaunchTimes(QString &desktopfp); bool setAppLockState(QString &desktopfp, size_t num); + //拖动改变置顶和收藏应用位置 + bool changeFavoriteAppPos(const QString &desktopfp, size_t pos); + bool changeTopAppPos(const QString &desktopfp, size_t pos); + bool getAllAppDesktopList(QStringList &list); bool getFavoritesAppList(QStringList &list); bool getTopAppList(QStringList &list); bool getLaunchTimesAppList(QStringList &list); bool getAppCategory(QString &desktopfp, QString &category); - bool getAppInfoResults(QVector &appInfoResults); + //获取所有应用信息并存到一个结构体中 + bool getAppInfoResults(QVector &appInfoResults); + //获取单个应用的某个状态(锁定,置顶,打开状态,收藏) bool getAppLockState(QString &desktopfp, size_t &num); bool getAppTopState(QString &desktopfp, size_t &num); bool getAppLaunchedState(QString &desktopfp, size_t &num); bool getAppFavoriteState(QString &desktopfp, size_t &num); + //添加快捷方式 bool addAppShortcut2Desktop(QString &desktopfp); bool addAppShortcut2Panel(QString &desktopfp); - bool getInstallAppMap(QMultiMap &installAppMap); + //搜索接口 bool searchInstallApp(QString &keyWord, QStringList &installAppInfoRes); bool searchInstallApp(QStringList &keyWord, QStringList &installAppInfoRes); @@ -49,10 +61,17 @@ private: bool openDataBase(); void closeDataBase(); + QDBusInterface *m_interface = nullptr; + AppInfoTable *q = nullptr; - QSqlDatabase *m_database = nullptr; + QSqlDatabase m_database; QString m_ConnectionName; +public Q_SLOTS: + void sendAppDBItemsUpdate(QVector results); + void sendAppDBItemsAdd(QVector results); + void sendAppDBItemsDelete(QStringList desktopfps); + }; diff --git a/libsearch/appdata/app-info-table.cpp b/libsearch/appdata/app-info-table.cpp index 8201547..2717745 100644 --- a/libsearch/appdata/app-info-table.cpp +++ b/libsearch/appdata/app-info-table.cpp @@ -1,3 +1,6 @@ +#include "app-info-table.h" +#include "app-info-table-private.h" + #include #include #include @@ -11,13 +14,23 @@ #include #include #include -#include "app-info-table.h" -#include "app-info-table-private.h" -#include "../ukui-search-app-data-service/app-db-common-defines.h" using namespace UkuiSearch; -AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent), q(parent), m_database(new QSqlDatabase) + +AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent), q(parent), m_database(QSqlDatabase()) { + m_interface = new QDBusInterface("com.ukui.search.appdb.service", + "/org/ukui/search/appDataBase", + "org.ukui.search.appdb"); + + if (!m_interface->isValid()) { + qCritical() << "Create privateDirWatcher Interface Failed Because: " << QDBusConnection::sessionBus().lastError(); + return; + } else { + connect(m_interface, SIGNAL(appDBItemsAdd(QVector)), this, SLOT(sendAppDBItemsAdd(QVector))); + connect(m_interface, SIGNAL(appDBItemsUpdate(QVector)), this, SLOT(sendAppDBItemsUpdate(QVector))); + connect(m_interface, SIGNAL(appDBItemsDelete(QStringList)), this, SLOT(sendAppDBItemsDelete(QStringList))); + } while(1) { srand(QTime(0,0,0).secsTo(QTime::currentTime())); m_ConnectionName = QString::fromStdString(std::to_string(rand()));//随机生产链接 @@ -27,26 +40,26 @@ AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent) qDebug() << "App info database currunt connection name:" << m_ConnectionName; if (!this->openDataBase()) { Q_EMIT q->DBOpenFailed(); - qWarning() << "Fail to open App DataBase, because:" << m_database->lastError(); + qWarning() << "Fail to open App DataBase, because:" << m_database.lastError(); } } bool AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, size_t num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH='%2'") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(num) .arg(desktopfp); if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database->lastError(); + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -59,19 +72,19 @@ bool AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, size_t num) bool AppInfoTablePrivate::setAppTopState(QString &desktopfp, size_t num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(num) .arg(desktopfp); if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database->lastError(); + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -84,20 +97,20 @@ bool AppInfoTablePrivate::setAppTopState(QString &desktopfp, size_t num) bool AppInfoTablePrivate::setAppLaunchTimes(QString &desktopfp, size_t num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); QString 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(num) .arg(1) .arg(desktopfp); if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database->lastError(); + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -110,8 +123,8 @@ bool AppInfoTablePrivate::setAppLaunchTimes(QString &desktopfp, size_t num) bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); if (sql.exec(cmd)) { if (sql.next()) { @@ -121,7 +134,7 @@ bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) .arg(1) .arg(desktopfp); if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database->lastError(); + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } } else { @@ -132,9 +145,9 @@ bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) qWarning() << "Failed to exec:" << cmd; res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -147,19 +160,19 @@ bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) bool AppInfoTablePrivate::setAppLockState(QString &desktopfp, size_t num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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)) { - qWarning() << "Set app favorites state failed!" << m_database->lastError(); + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -169,38 +182,126 @@ bool AppInfoTablePrivate::setAppLockState(QString &desktopfp, size_t num) return res; } +bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, size_t pos) +{ + bool res(true); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QString cmd = QString("SELECT FAVORITES FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); + //记录应用原位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + if (sql.next()) { + cmd = QString("UPDATE appInfo SET FAVORITES = FAVORITES + 1 WHRER FAVORITES > %1 AND FAVORITES < %2") + .arg(sql.value(0).toUInt()) + .arg(pos); + } else { + qWarning() << "Fail to change favorite-app pos when exec next, because: " << m_database.lastError(); + } + } + //更新范围内的应用的位置(原位置和新位置之间) + if (!sql.exec(cmd)) { + qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + cmd = QString("UPDATE appInfo SET FAVORITES = %1 WHERE DESKTOP_FILE_PATH = %2") + .arg(pos) + .arg(desktopfp); + } + //更新应用位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } + + if (!m_database.commit()) { + qWarning() << "Failed to commit when exec: " << cmd; + m_database.rollback(); + res = false; + } + + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + + return res; +} + +bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, size_t pos) +{ + bool res(true); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QString cmd = QString("SELECT TOP FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); + //记录应用原位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + if (sql.next()) { + cmd = QString("UPDATE appInfo SET TOP = TOP + 1 WHRER TOP > %1 AND TOP < %2") + .arg(sql.value(0).toUInt()) + .arg(pos); + } else { + qWarning() << "Fail to change top-app pos when exec next, because: " << m_database.lastError(); + } + } + //更新范围内的应用的位置(原位置和新位置之间) + if (!sql.exec(cmd)) { + qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + cmd = QString("UPDATE appInfo SET TOP = %1 WHERE DESKTOP_FILE_PATH = %2") + .arg(pos) + .arg(desktopfp); + } + //更新应用位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } + + if (!m_database.commit()) { + qWarning() << "Failed to commit when exec: " << cmd; + m_database.rollback(); + res = false; + } + + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + + return res; +} + bool AppInfoTablePrivate::getAllAppDesktopList(QStringList &list) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); - if (sql.exec(cmd)) { - while (sql.next()) { - list.append(sql.value(0).toString()); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); - res = false; - } - if (!m_database->commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); - res = false; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); + + if (sql.exec(cmd)) { + while (sql.next()) { + list.append(sql.value(0).toString()); } } else { - qWarning() << "Failed to start transaction mode!!!"; + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } + return res; } bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); - QSqlQuery sqlque(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QSqlQuery sqlque(m_database); QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE FAVORITES!=0 ORDER BY FAVORITES"); int count = 0; if (sql.exec(cmd)) { @@ -210,18 +311,18 @@ bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) .arg(++count) .arg(sql.value(0).toString()); if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; break; } } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -234,9 +335,9 @@ bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) bool AppInfoTablePrivate::getTopAppList(QStringList &list) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); - QSqlQuery sqlque(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QSqlQuery sqlque(m_database); QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE TOP!=0 ORDER BY TOP"); int count = 0; if (sql.exec(cmd)) { @@ -246,18 +347,18 @@ bool AppInfoTablePrivate::getTopAppList(QStringList &list) .arg(++count) .arg(sql.value(0).toString()); if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; break; } } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -270,9 +371,9 @@ bool AppInfoTablePrivate::getTopAppList(QStringList &list) bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); - QSqlQuery sqlque(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QSqlQuery sqlque(m_database); QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo ORDER BY LAUNCH_TIMES"); int count = 0; if (sql.exec(cmd)) { @@ -282,18 +383,18 @@ bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) .arg(++count) .arg(sql.value(0).toString()); if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; break; } } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -306,24 +407,24 @@ bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) bool AppInfoTablePrivate::getAppCategory(QString &desktopfp, QString &category) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -333,15 +434,15 @@ bool AppInfoTablePrivate::getAppCategory(QString &desktopfp, QString &category) return res; } -bool AppInfoTablePrivate::getAppInfoResults(QVector &appInfoResults) +bool AppInfoTablePrivate::getAppInfoResults(QVector &appInfoResults) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,CATEGORY,TOP,FAVORITES,LAUNCH_TIMES,LOCK FROM appInfo"); + if (m_database.transaction()) { + 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()) { - AppInfoTable::AppInfoResult result; + AppInfoResult result; result.desktopPath = sql.value(0).toString(); result.appLocalName = sql.value(1).toString(); result.iconName = sql.value(2).toString(); @@ -350,15 +451,16 @@ bool AppInfoTablePrivate::getAppInfoResults(QVector result.favorate = sql.value(5).toInt(); result.launchTimes = sql.value(6).toInt(); result.lock = sql.value(7).toInt(); + result.firstLetter = sql.value(8).toString(); appInfoResults.append(std::move(result)); } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -371,24 +473,24 @@ bool AppInfoTablePrivate::getAppInfoResults(QVector bool AppInfoTablePrivate::getAppLockState(QString &desktopfp, size_t &num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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()) { num = sql.value(0).toInt(); } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -401,24 +503,24 @@ bool AppInfoTablePrivate::getAppLockState(QString &desktopfp, size_t &num) bool AppInfoTablePrivate::getAppTopState(QString &desktopfp, size_t &num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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()) { num = sql.value(0).toInt(); } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -431,24 +533,24 @@ bool AppInfoTablePrivate::getAppTopState(QString &desktopfp, size_t &num) bool AppInfoTablePrivate::getAppLaunchedState(QString &desktopfp, size_t &num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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()) { num = sql.value(0).toInt(); } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -461,24 +563,24 @@ bool AppInfoTablePrivate::getAppLaunchedState(QString &desktopfp, size_t &num) bool AppInfoTablePrivate::getAppFavoriteState(QString &desktopfp, size_t &num) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + 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()) { num = sql.value(0).toInt(); } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -534,8 +636,8 @@ bool AppInfoTablePrivate::addAppShortcut2Panel(QString &desktopfp) bool AppInfoTablePrivate::searchInstallApp(QString &keyWord, QStringList &installAppInfoRes) { bool res(true); - if (m_database->transaction()) { - QSqlQuery sql(*m_database); + if (m_database.transaction()) { + QSqlQuery sql(m_database); QString cmd; if (keyWord.size() < 2) { cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON FROM appInfo WHERE LOCAL_NAME OR NAME_EN OR NAME_ZH OR FIRST_LETTER_OF_PINYIN LIKE '%%0%' ORDER BY FAVORITES DESC") @@ -550,12 +652,12 @@ bool AppInfoTablePrivate::searchInstallApp(QString &keyWord, QStringList &instal installAppInfoRes << sql.value(0).toString() << sql.value(1).toString() << sql.value(2).toString(); } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -568,8 +670,8 @@ bool AppInfoTablePrivate::searchInstallApp(QString &keyWord, QStringList &instal bool AppInfoTablePrivate::searchInstallApp(QStringList &keyWord, QStringList &installAppInfoRes) { bool res(true); - if (m_database->transaction() or keyWord.size() != 0) { - QSqlQuery sql(*m_database); + if (m_database.transaction() or keyWord.size() != 0) { + QSqlQuery sql(m_database); QString cmd; if (keyWord.at(0).size() < 2) { cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,NAME_EN,NAME_ZH,FIRST_LETTER_OF_PINYIN FROM appInfo" @@ -595,12 +697,12 @@ bool AppInfoTablePrivate::searchInstallApp(QStringList &keyWord, QStringList &in installAppInfoRes << sql.value(0).toString() << sql.value(1).toString() << sql.value(2).toString(); } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError(); + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); res = false; } - if (!m_database->commit()) { + if (!m_database.commit()) { qWarning() << "Failed to commit !" << cmd; - m_database->rollback(); + m_database.rollback(); res = false; } } else { @@ -648,7 +750,7 @@ bool AppInfoTablePrivate::uninstallApp(QString &desktopfp) QString AppInfoTablePrivate::lastError() const { - return m_database->lastError().text(); + return m_database.lastError().text(); } AppInfoTablePrivate::~AppInfoTablePrivate() @@ -658,9 +760,9 @@ AppInfoTablePrivate::~AppInfoTablePrivate() bool AppInfoTablePrivate::initDateBaseConnection() { - m_database->setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME); - if(!m_database->open()) { - qWarning() << m_database->lastError(); + m_database.setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME); + if(!m_database.open()) { + qWarning() << m_database.lastError(); return false; // QApplication::quit(); } @@ -669,10 +771,10 @@ bool AppInfoTablePrivate::initDateBaseConnection() bool AppInfoTablePrivate::openDataBase() { - *m_database = QSqlDatabase::addDatabase("QSQLITE", m_ConnectionName); - m_database->setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME); + m_database = QSqlDatabase::addDatabase("QSQLITE", m_ConnectionName); + m_database.setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME); - if(!m_database->open()) { + if(!m_database.open()) { return false; } return true; @@ -680,11 +782,26 @@ bool AppInfoTablePrivate::openDataBase() void AppInfoTablePrivate::closeDataBase() { - m_database->close(); - delete m_database; + m_database.close(); +// delete m_database; QSqlDatabase::removeDatabase(m_ConnectionName); } +void AppInfoTablePrivate::sendAppDBItemsUpdate(QVector results) +{ + Q_EMIT q->appDBItems2BUpdate(results); +} + +void AppInfoTablePrivate::sendAppDBItemsAdd(QVector results) +{ + Q_EMIT q->appDBItems2BAdd(results); +} + +void AppInfoTablePrivate::sendAppDBItemsDelete(QStringList desktopfps) +{ + Q_EMIT q->appDBItems2BDelete(desktopfps); +} + AppInfoTable::AppInfoTable(QObject *parent) : QObject(parent), d(new AppInfoTablePrivate(this)) { } @@ -739,7 +856,17 @@ bool AppInfoTable::getAppCategory(QString &desktopfp, QString &category) return d->getAppCategory(desktopfp, category); } -bool AppInfoTable::getAppInfoResults(QVector &appInfoResults) +bool AppInfoTable::changeFavoriteAppPos(const QString &desktopfp, size_t pos) +{ + return d->changeFavoriteAppPos(desktopfp, pos); +} + +bool AppInfoTable::changeTopAppPos(const QString &desktopfp, size_t pos) +{ + return d->changeTopAppPos(desktopfp, pos); +} + +bool AppInfoTable::getAppInfoResults(QVector &appInfoResults) { return d->getAppInfoResults(appInfoResults); } diff --git a/libsearch/appdata/app-info-table.h b/libsearch/appdata/app-info-table.h index 04cf34e..5ff4e5a 100644 --- a/libsearch/appdata/app-info-table.h +++ b/libsearch/appdata/app-info-table.h @@ -2,54 +2,89 @@ #define APPINFOTABLE_H #include +#include "app-db-common.h" + namespace UkuiSearch { + class AppInfoTablePrivate; class AppInfoTable : public QObject { Q_OBJECT - -public: - typedef struct appInfoResult - { - appInfoResult() { - top = 0; - favorate = 0; - launchTimes = 0; - lock = 0; - } - - QString desktopPath; - QString iconName; - QString appLocalName; - QString firstLetter; - QString category; - size_t top; - size_t favorate; - size_t launchTimes; - size_t lock; - - } AppInfoResult; - public: explicit AppInfoTable(QObject *parent = nullptr); AppInfoTable(AppInfoTable &) = delete; AppInfoTable &operator =(const AppInfoTable &) = delete; + /** + * @brief AppInfoTable::setAppFavoritesState + * set the favorites state of the app + * @param desktopfp: the desktop file path of app + * @param num: the favorites app's order(from 1) + * @return bool: true if success, else false + */ bool setAppFavoritesState(QString &desktopfp, size_t num); + + /** + * @brief AppInfoTable::setAppTopState + * set the top state of the app + * @param desktopfp: the desktop file path of app + * @param num: the top app's order(from 1) + * @return bool: true if success, else false + */ bool setAppTopState(QString &desktopfp, size_t num); + /** + * @brief AppInfoTable::getAllAppDesktopList + * get the desktop file paths of all apps + * @param list: a stringlist include all paths + * @return bool: true if success, else false + */ bool getAllAppDesktopList(QStringList &list); + + /** + * @brief AppInfoTable::getFavoritesAppList + * get all favorites apps + * @param list: a stringlist include all apps' paths + * @return bool: true if success, else false + */ bool getFavoritesAppList(QStringList &list); + + /** + * @brief AppInfoTable::getTopAppList + * get all top apps + * @param list: a stringlist include all apps' paths + * @return bool: true if success, else false + */ bool getTopAppList(QStringList &list); + bool getLaunchTimesAppList(QStringList &list); bool getAppCategory(QString &desktopfp, QString &category); /** - * @brief getAppInfoResults - * @param appInfoResults - * @return + * @brief AppInfoTable::changeFavoriteAppPos + * change the position of the app which is one of the Favorites Apps + * @param desktopfp: desktop file path of app + * @param pos: the position which the app will be changed into + * @return bool: true if success, else false */ - bool getAppInfoResults(QVector &appInfoResults); + bool changeFavoriteAppPos(const QString &desktopfp, size_t pos); + + /** + * @brief AppInfoTable::changeTopAppPos + * hange the position of the app which is one of the Top Apps + * @param desktopfp: desktop file path of app + * @param pos: the position which the app will be changed into + * @return bool: true if success, else false + */ + bool changeTopAppPos(const QString &desktopfp, size_t pos); + + /** + * @brief AppInfoTable::getAppInfoResults + * Get all App infos by passing AppInforesult Vector. + * @param AppInfoResults: a struct which includes all infos of each application + * @return bool: true if success, else false + */ + bool getAppInfoResults(QVector &appInfoResults); bool getAppLockState(QString &desktopfp, size_t &num); bool getAppTopState(QString &desktopfp, size_t &num); @@ -65,8 +100,9 @@ public: bool uninstallApp(QString &desktopfp); /** - * @brief lastError - * @return + * @brief AppInfoTable::lastError + * the last error of the database + * @return QString: the text of the last error */ QString lastError(void) const; @@ -76,9 +112,12 @@ private: bool updateAppLaunchTimes(QString &desktopfp); AppInfoTablePrivate *d; + Q_SIGNALS: void DBOpenFailed(); - + void appDBItems2BUpdate(QVector); + void appDBItems2BAdd(QVector); + void appDBItems2BDelete(QStringList); }; } diff --git a/libsearch/libsearch.pro b/libsearch/libsearch.pro index 79da936..18b3069 100644 --- a/libsearch/libsearch.pro +++ b/libsearch/libsearch.pro @@ -50,6 +50,7 @@ SOURCES += \ libsearch.cpp HEADERS += \ + app-db-common.h \ common.h \ file-utils.h \ global-settings.h \ diff --git a/ukui-search-app-data-service/app-db-common-defines.h b/ukui-search-app-data-service/app-db-common-defines.h deleted file mode 100644 index e3c1225..0000000 --- a/ukui-search-app-data-service/app-db-common-defines.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef APPDBCOMMONDEFINES_H -#define APPDBCOMMONDEFINES_H -#include - -namespace UkuiSearch { - -#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/" -#define APP_DATABASE_NAME "app-info.db" - -} -#endif // APPDBCOMMONDEFINES_H diff --git a/ukui-search-app-data-service/app-db-manager.cpp b/ukui-search-app-data-service/app-db-manager.cpp index a4b95db..1c2ddcf 100644 --- a/ukui-search-app-data-service/app-db-manager.cpp +++ b/ukui-search-app-data-service/app-db-manager.cpp @@ -1,10 +1,11 @@ +#include "app-db-manager.h" +#include "file-utils.h" +#include "convert-winid-to-desktop.h" + #include #include #include #include -#include "app-db-manager.h" -#include "file-utils.h" -#include "convert-winid-to-desktop.h" #define GENERAL_APP_DESKTOP_PATH "/usr/share/applications/" #define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications/" @@ -71,6 +72,8 @@ AppDBManager::AppDBManager(QObject *parent) : QObject(parent), m_database(QSqlDa if (!m_database.commit()) { qWarning() << "Failed to commit !"; m_database.rollback(); + } else { + Q_EMIT this->finishHandleAppDB(); } } else { qWarning() << "Failed to start transaction mode!!!"; @@ -111,7 +114,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")//拼音和英文全拼 .arg("ICON TEXT")//图标名称(或路径) .arg("TYPE TEXT")//应用类型 .arg("CATEGORY TEXT")//应用分类 @@ -406,6 +409,10 @@ bool AppDBManager::updateLocaleData2DB(QString desktopPath) res = false; } if (res) { + AppInfoResult result; + result.appLocalName = localName; + result.firstLetter = firstLetter2All; + Q_EMIT this->appDBItemUpdate(result); qDebug() << "Already to update the locale app-data of " << desktopPath; } else { qDebug() << "Fail to update the locale app-data of " << desktopPath; @@ -421,6 +428,8 @@ void AppDBManager::initDataBase() if (!m_database.commit()) { qWarning() << "Failed to commit !"; m_database.rollback(); + } else { + Q_EMIT this->finishHandleAppDB(); } } else { qWarning() << "Failed to start transaction mode!!!"; @@ -482,11 +491,11 @@ bool AppDBManager::addAppDesktopFile2DB(QString &desktopfd) desktopfile.load(desktopfd); QString hanzi, pinyin, firstLetterOfPinyin; QString localName = desktopfile.localizedValue("Name", "NULL").toString(); - QString firstLtter2All = localName; + QString firstLetter2All = localName; bool isHanzi = true; if (localName.contains(QRegExp("[\\x4e00-\\x9fa5]+"))) { - firstLtter2All = FileUtils::findMultiToneWords(localName).at(0); + firstLetter2All = FileUtils::findMultiToneWords(localName).at(0); } if (desktopfile.contains("Name[zh_CN]")) { @@ -524,7 +533,7 @@ bool AppDBManager::addAppDesktopFile2DB(QString &desktopfd) .arg(hanzi) .arg(pinyin) .arg(firstLetterOfPinyin) - .arg(firstLtter2All) + .arg(firstLetter2All) .arg(desktopfile.value("Icon").toString()) .arg(desktopfile.value("Type").toString()) .arg(desktopfile.value("Categories").toString()) @@ -541,6 +550,13 @@ bool AppDBManager::addAppDesktopFile2DB(QString &desktopfd) 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!"; } else { qDebug() << "app database add " << desktopfd << "failed!"; @@ -558,6 +574,7 @@ bool AppDBManager::deleteAppDesktopFile2DB(const QString &desktopfd) res = false; } if (res) { + Q_EMIT this->appDBItemDelete(desktopfd); qDebug() << "app database delete " << desktopfd << "success!"; } else { qDebug() << "app database delete " << desktopfd << "failed!"; @@ -612,7 +629,7 @@ bool AppDBManager::updateAppDesktopFile2DB(QString &desktopfd) "NAME_ZH='%3'" ",PINYIN_NAME='%4'," "FIRST_LETTER_OF_PINYIN='%5'," - "FIRST_LETTER_ALL='%6'" + "FIRST_LETTER_ALL='%6'," "ICON='%7'," "TYPE='%8'," "CATEGORY='%9'," @@ -639,6 +656,13 @@ bool AppDBManager::updateAppDesktopFile2DB(QString &desktopfd) 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->appDBItemUpdate(result); qDebug() << "app database update " << desktopfd << "success!"; } else { qDebug() << "app database update " << desktopfd << "failed!"; @@ -654,14 +678,19 @@ bool AppDBManager::updateAppLaunchTimes(QString &desktopfp) QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); if (sql.exec(cmd)) { if (sql.next()) { + int launchTimes = sql.value(0).toInt() + 1; 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(sql.value(0).toInt() + 1) + .arg(launchTimes) .arg(1) .arg(desktopfp); if (!sql.exec(cmd)) { qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; + } else { + AppInfoResult result; + result.launchTimes = launchTimes; + Q_EMIT this->appDBItemUpdate(result); } } else { qWarning() << "Failed to exec next!" << cmd; @@ -675,6 +704,8 @@ bool AppDBManager::updateAppLaunchTimes(QString &desktopfp) qWarning() << "Failed to commit !" << cmd; m_database.rollback(); res = false; + } else { + Q_EMIT this->finishHandleAppDB(); } } else { qWarning() << "Failed to start transaction mode!!!"; diff --git a/ukui-search-app-data-service/app-db-manager.h b/ukui-search-app-data-service/app-db-manager.h index 604c81c..5bd0592 100644 --- a/ukui-search-app-data-service/app-db-manager.h +++ b/ukui-search-app-data-service/app-db-manager.h @@ -1,6 +1,8 @@ #ifndef APPDBMANAGER_H #define APPDBMANAGER_H +#include "app-db-common.h" + #include #include #include @@ -12,7 +14,6 @@ #include #include #include -#include "app-db-common-defines.h" #define CONNECTION_NAME QLatin1String("ukss-appdb-connection") @@ -130,7 +131,11 @@ private: //原本额外排除的目录,不知道额外的原因,有可能之后有问题--bjj20220621 "/usr/share/applications/screensavers" }; - +Q_SIGNALS: + void appDBItemUpdate(const AppInfoResult&); + void appDBItemAdd(const AppInfoResult&); + 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 new file mode 100644 index 0000000..6cc081e --- /dev/null +++ b/ukui-search-app-data-service/signal-transformer.cpp @@ -0,0 +1,47 @@ +#include "signal-transformer.h" + +QMutex SignalTransformer::s_mutex; + +SignalTransformer *SignalTransformer::getTransformer() +{ + static SignalTransformer *instance = new SignalTransformer(); + return instance; +} + +void SignalTransformer::handleItemInsert(const AppInfoResult &item) +{ + QMutexLocker locker(&s_mutex); + m_items2BInsert.append(item); +} + +void SignalTransformer::handleItemUpdate(const AppInfoResult &item) +{ + QMutexLocker locker(&s_mutex); + m_items2BUpdate.append(item); +} + +void SignalTransformer::handleItemDelete(const QString &desktopfp) +{ + QMutexLocker locker(&s_mutex); + m_items2BDelete.append(desktopfp); +} + +void SignalTransformer::handleSignalTransform() +{ + QMutexLocker locker(&s_mutex); + Q_EMIT this->appDBItemsAdd(m_items2BInsert); + Q_EMIT this->appDBItemsUpdate(m_items2BUpdate); + Q_EMIT this->appDBItemsDelete(m_items2BDelete); + m_items2BInsert.clear(); + m_items2BUpdate.clear(); + m_items2BDelete.clear(); +} + +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::finishHandleAppDB, this, &SignalTransformer::handleSignalTransform); +} + diff --git a/ukui-search-app-data-service/signal-transformer.h b/ukui-search-app-data-service/signal-transformer.h new file mode 100644 index 0000000..4f2d4fa --- /dev/null +++ b/ukui-search-app-data-service/signal-transformer.h @@ -0,0 +1,43 @@ +#ifndef SIGNALTRANSFORMER_H +#define SIGNALTRANSFORMER_H + +#include +#include +#include +#include "app-db-manager.h" + +using namespace UkuiSearch; + +class SignalTransformer : public QObject +{ + Q_CLASSINFO("D-Bus Interface","org.ukui.search.appdb") + + Q_OBJECT + +public: + static SignalTransformer *getTransformer(); + + static QMutex s_mutex; + +public Q_SLOTS: + void handleItemInsert(const AppInfoResult &item); + void handleItemUpdate(const AppInfoResult &item); + void handleItemDelete(const QString &desktopfp); + void handleSignalTransform(); + +private: + SignalTransformer(QObject *parent = nullptr); + SignalTransformer(const SignalTransformer &) = delete; + SignalTransformer& operator = (const SignalTransformer&) = delete; + + QVector m_items2BUpdate; + QVector m_items2BInsert; + QStringList m_items2BDelete; + +Q_SIGNALS: + void appDBItemsUpdate(QVector); + void appDBItemsAdd(QVector); + void appDBItemsDelete(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 176d061..1acef86 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 @@ -1,6 +1,11 @@ -#include #include "ukui-search-app-data-service.h" #include "app-db-manager.h" +#include "signal-transformer.h" + +#include +#include +#include +#include using namespace UkuiSearch; @@ -12,9 +17,24 @@ UkuiSearchAppDataService::UkuiSearchAppDataService(int &argc, char *argv[], cons setQuitOnLastWindowClosed(false); if (!this->isRunning()) { - qDebug() << "First running"; + qDebug() << "First running, I'm in app-db manager dbus rigister."; + + qRegisterMetaType("AppInfoResult"); + qRegisterMetaType>("QVector"); + + qDBusRegisterMetaType(); + qDBusRegisterMetaType>(); + AppDBManager::getInstance(); + QDBusConnection sessionBus = QDBusConnection::sessionBus(); + if (!sessionBus.registerService("com.ukui.search.appdb.service")) { + qCritical() << "QDbus register service failed reason:" << sessionBus.lastError(); + } + if(!sessionBus.registerObject("/org/ukui/search/appDataBase", SignalTransformer::getTransformer(), QDBusConnection::ExportAllSignals)) { + qCritical() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); + } + connect(this, &QtSingleApplication::messageReceived, [ & ](QString msg) { this->parseCmd(msg, true); }); 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 3a51d34..a48aa90 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 @@ -29,13 +29,14 @@ SOURCES += \ main.cpp \ convert-winid-to-desktop.cpp \ app-db-manager.cpp \ + signal-transformer.cpp \ ukui-search-app-data-service.cpp \ HEADERS += \ convert-winid-to-desktop.h \ app-db-manager.h \ + signal-transformer.h \ ukui-search-app-data-service.h \ - app-db-common-defines.h \ target.path = /usr/bin INSTALLS += target From 27f28df33d8436390c3843571fc658e23273e6fc Mon Sep 17 00:00:00 2001 From: JunjieBai Date: Tue, 28 Jun 2022 14:00:57 +0800 Subject: [PATCH 2/2] Add two timers to handle multi signals in a short time. Modify the update logic, add update signals while set or change pos of top&favorites. Adjust the struct of the app info table. --- libsearch/app-db-common.h | 8 +- libsearch/appdata/app-info-table-private.h | 23 +- libsearch/appdata/app-info-table.cpp | 521 +++++++++--------- libsearch/appdata/app-info-table.h | 34 +- .../app-db-manager.cpp | 95 +++- ukui-search-app-data-service/app-db-manager.h | 18 +- .../ukui-search-app-data-service.pro | 4 +- 7 files changed, 391 insertions(+), 312 deletions(-) diff --git a/libsearch/app-db-common.h b/libsearch/app-db-common.h index c8ef2dd..fba443b 100644 --- a/libsearch/app-db-common.h +++ b/libsearch/app-db-common.h @@ -18,16 +18,16 @@ struct AppInfoResult QString firstLetter; QString category; int top; - int favorate; + int favorite; int launchTimes; int lock; - AppInfoResult() : top(0), favorate(0), launchTimes(0), lock(0) {} + AppInfoResult() : top(0), favorite(0), launchTimes(0), lock(0) {} friend QDBusArgument &operator << (QDBusArgument &argument, const AppInfoResult &infoResult) { argument.beginStructure(); argument << infoResult.desktopPath << infoResult.iconName << infoResult.appLocalName << infoResult.firstLetter - << infoResult.category << infoResult.top << infoResult.favorate << infoResult.launchTimes << infoResult.lock; + << infoResult.category << infoResult.top << infoResult.favorite << infoResult.launchTimes << infoResult.lock; argument.endStructure(); return argument; } @@ -36,7 +36,7 @@ struct AppInfoResult { argument.beginStructure(); argument >> infoResult.desktopPath >> infoResult.iconName >> infoResult.appLocalName >> infoResult.firstLetter - >> infoResult.category >> infoResult.top >> infoResult.favorate >> infoResult.launchTimes >> infoResult.lock; + >> infoResult.category >> infoResult.top >> infoResult.favorite >> infoResult.launchTimes >> infoResult.lock; argument.endStructure(); return argument; diff --git a/libsearch/appdata/app-info-table-private.h b/libsearch/appdata/app-info-table-private.h index c0ef60d..6449993 100644 --- a/libsearch/appdata/app-info-table-private.h +++ b/libsearch/appdata/app-info-table-private.h @@ -19,21 +19,10 @@ public: bool setAppFavoritesState(QString &desktopfp, size_t num); bool setAppTopState(QString &desktopfp, size_t num); - //下面三个暂时未封装 - bool setAppLaunchTimes(QString &desktopfp, size_t num); - bool updateAppLaunchTimes(QString &desktopfp); - bool setAppLockState(QString &desktopfp, size_t num); - //拖动改变置顶和收藏应用位置 bool changeFavoriteAppPos(const QString &desktopfp, size_t pos); bool changeTopAppPos(const QString &desktopfp, size_t pos); - bool getAllAppDesktopList(QStringList &list); - bool getFavoritesAppList(QStringList &list); - bool getTopAppList(QStringList &list); - bool getLaunchTimesAppList(QStringList &list); - bool getAppCategory(QString &desktopfp, QString &category); - //获取所有应用信息并存到一个结构体中 bool getAppInfoResults(QVector &appInfoResults); @@ -42,6 +31,7 @@ public: bool getAppTopState(QString &desktopfp, size_t &num); bool getAppLaunchedState(QString &desktopfp, size_t &num); bool getAppFavoriteState(QString &desktopfp, size_t &num); + bool getAppCategory(QString &desktopfp, QString &category); //添加快捷方式 bool addAppShortcut2Desktop(QString &desktopfp); @@ -51,10 +41,21 @@ public: bool searchInstallApp(QString &keyWord, QStringList &installAppInfoRes); bool searchInstallApp(QStringList &keyWord, QStringList &installAppInfoRes); + //卸载应用 bool uninstallApp(QString &desktopfp); + //数据库错误信息 QString lastError(void) const; + //下面的接口都不外放,暂时没啥用 + bool setAppLaunchTimes(QString &desktopfp, size_t num); + bool updateAppLaunchTimes(QString &desktopfp); + bool setAppLockState(QString &desktopfp, size_t num); + bool getAllAppDesktopList(QStringList &list); + bool getFavoritesAppList(QStringList &list); + bool getTopAppList(QStringList &list); + bool getLaunchTimesAppList(QStringList &list); + private: ~AppInfoTablePrivate(); bool initDateBaseConnection(); diff --git a/libsearch/appdata/app-info-table.cpp b/libsearch/appdata/app-info-table.cpp index 2717745..d99b881 100644 --- a/libsearch/appdata/app-info-table.cpp +++ b/libsearch/appdata/app-info-table.cpp @@ -61,6 +61,13 @@ bool AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, size_t num) qWarning() << "Failed to commit !" << cmd; m_database.rollback(); res = false; + } else { + QVector results; + AppInfoResult info; + info.desktopPath = desktopfp; + info.favorite = num; + results.append(std::move(info)); + Q_EMIT q->appDBItems2BUpdate(results); } } else { qWarning() << "Failed to start transaction mode!!!"; @@ -86,94 +93,13 @@ bool AppInfoTablePrivate::setAppTopState(QString &desktopfp, size_t num) qWarning() << "Failed to commit !" << cmd; m_database.rollback(); res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; -} - -bool AppInfoTablePrivate::setAppLaunchTimes(QString &desktopfp, size_t num) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString 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(num) - .arg(1) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; -} - -bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - 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(sql.value(0).toInt() + 1) - .arg(1) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } - } else { - qWarning() << "Failed to exec next!" << cmd; - res = false; - } } else { - qWarning() << "Failed to exec:" << cmd; - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; -} - -bool AppInfoTablePrivate::setAppLockState(QString &desktopfp, size_t num) -{ - bool res(true); - if (m_database.transaction()) { - 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)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; + QVector results; + AppInfoResult info; + info.desktopPath = desktopfp; + info.top = num; + results.append(std::move(info)); + Q_EMIT q->appDBItems2BUpdate(results); } } else { qWarning() << "Failed to start transaction mode!!!"; @@ -188,14 +114,17 @@ bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, size_t if (m_database.transaction()) { QSqlQuery sql(m_database); QString cmd = QString("SELECT FAVORITES FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); + int previousPos = 0; + //记录应用原位置 if (!sql.exec(cmd)) { qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; res = false; } else { if (sql.next()) { + previousPos = sql.value(0).toInt(); cmd = QString("UPDATE appInfo SET FAVORITES = FAVORITES + 1 WHRER FAVORITES > %1 AND FAVORITES < %2") - .arg(sql.value(0).toUInt()) + .arg(previousPos) .arg(pos); } else { qWarning() << "Fail to change favorite-app pos when exec next, because: " << m_database.lastError(); @@ -220,6 +149,22 @@ bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, size_t qWarning() << "Failed to commit when exec: " << cmd; m_database.rollback(); res = false; + } else { + cmd = QString("SELECT DESKTOP_FILE_PATH, FAVORITES FROM appInfo WHERE FAVORITES > %1 AND FAVORITES < %2") + .arg(previousPos) + .arg(pos); + if (!sql.exec(cmd)) { + qWarning() << "I'm going to send update favorites signal but fail to exec" << cmd; + } else { + QVector results; + while (sql.next()) { + AppInfoResult info; + info.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); + info.favorite = sql.value("FAVORITES").toInt(); + results.append(std::move(info)); + } + Q_EMIT q->appDBItems2BUpdate(results); + } } } else { @@ -236,14 +181,17 @@ bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, size_t pos) if (m_database.transaction()) { QSqlQuery sql(m_database); QString cmd = QString("SELECT TOP FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); + int previousPos = 0; + //记录应用原位置 if (!sql.exec(cmd)) { qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; res = false; } else { if (sql.next()) { + previousPos = sql.value(0).toInt(); cmd = QString("UPDATE appInfo SET TOP = TOP + 1 WHRER TOP > %1 AND TOP < %2") - .arg(sql.value(0).toUInt()) + .arg(previousPos) .arg(pos); } else { qWarning() << "Fail to change top-app pos when exec next, because: " << m_database.lastError(); @@ -268,139 +216,29 @@ bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, size_t pos) qWarning() << "Failed to commit when exec: " << cmd; m_database.rollback(); res = false; - } - - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - - return res; -} - -bool AppInfoTablePrivate::getAllAppDesktopList(QStringList &list) -{ - bool res(true); - QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); - - if (sql.exec(cmd)) { - while (sql.next()) { - list.append(sql.value(0).toString()); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - - return res; -} - -bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QSqlQuery sqlque(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE FAVORITES!=0 ORDER BY FAVORITES"); - int count = 0; - if (sql.exec(cmd)) { - while (sql.next()) { - list.append(sql.value(0).toString()); - cmd = QString("UPDATE appInfo SET FAVORITES=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(++count) - .arg(sql.value(0).toString()); - if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - break; - } - } } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; -} - -bool AppInfoTablePrivate::getTopAppList(QStringList &list) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QSqlQuery sqlque(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE TOP!=0 ORDER BY TOP"); - int count = 0; - if (sql.exec(cmd)) { - while (sql.next()) { - list.append(sql.value(0).toString()); - cmd = QString("UPDATE appInfo SET TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(++count) - .arg(sql.value(0).toString()); - if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - break; + cmd = QString("SELECT DESKTOP_FILE_PATH, TOP FROM appInfo WHERE TOP > %1 AND TOP < %2") + .arg(previousPos) + .arg(pos); + if (!sql.exec(cmd)) { + qWarning() << "I'm going to send update top signal but fail to exec" << cmd; + } else { + QVector results; + while (sql.next()) { + AppInfoResult info; + info.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); + info.favorite = sql.value("TOP").toInt(); + results.append(std::move(info)); } + Q_EMIT q->appDBItems2BUpdate(results); } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; -} -bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QSqlQuery sqlque(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo ORDER BY LAUNCH_TIMES"); - int count = 0; - if (sql.exec(cmd)) { - while (sql.next()) { - list.append(sql.value(0).toString()); - cmd = QString("UPDATE appInfo SET TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(++count) - .arg(sql.value(0).toString()); - if (!sqlque.exec(cmd)) { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - break; - } - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } } else { qWarning() << "Failed to start transaction mode!!!"; res = false; } + return res; } @@ -448,7 +286,7 @@ bool AppInfoTablePrivate::getAppInfoResults(QVector &appInfoResul result.iconName = sql.value(2).toString(); result.category = sql.value(3).toString(); result.top = sql.value(4).toInt(); - result.favorate = sql.value(5).toInt(); + result.favorite = sql.value(5).toInt(); result.launchTimes = sql.value(6).toInt(); result.lock = sql.value(7).toInt(); result.firstLetter = sql.value(8).toString(); @@ -715,7 +553,13 @@ bool AppInfoTablePrivate::searchInstallApp(QStringList &keyWord, QStringList &in bool AppInfoTablePrivate::uninstallApp(QString &desktopfp) { bool res(false); + QString cmd = QString("kylin-uninstaller %1") + .arg(desktopfp.toLocal8Bit().data()); + res = QProcess::startDetached(cmd); + qDebug() << "kylin-uninstaller uninstall:" << cmd << res; + return res; + /* bool isOsReleaseUbuntu(false); QFile file("/etc/os-release"); if (file.open(QFile::ReadOnly)) { @@ -744,8 +588,8 @@ bool AppInfoTablePrivate::uninstallApp(QString &desktopfp) res = QProcess::startDetached(cmd); qDebug() << "dpkg -S uninstall:" << cmd << res; } - return res; + */ } QString AppInfoTablePrivate::lastError() const @@ -753,6 +597,182 @@ QString AppInfoTablePrivate::lastError() const return m_database.lastError().text(); } +bool AppInfoTablePrivate::setAppLaunchTimes(QString &desktopfp, size_t num) +{ + bool res(true); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QString 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(num) + .arg(1) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } + if (!m_database.commit()) { + qWarning() << "Failed to commit !" << cmd; + m_database.rollback(); + res = false; + } + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + return res; +} + +bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) +{ + bool res(true); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); + if (sql.exec(cmd)) { + if (sql.next()) { + 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(sql.value(0).toInt() + 1) + .arg(1) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } + } else { + qWarning() << "Failed to exec next!" << cmd; + res = false; + } + } else { + qWarning() << "Failed to exec:" << cmd; + res = false; + } + if (!m_database.commit()) { + qWarning() << "Failed to commit !" << cmd; + m_database.rollback(); + res = false; + } + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + return res; +} + +bool AppInfoTablePrivate::setAppLockState(QString &desktopfp, size_t num) +{ + bool res(true); + if (m_database.transaction()) { + 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)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } + if (!m_database.commit()) { + qWarning() << "Failed to commit !" << cmd; + m_database.rollback(); + res = false; + } + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + return res; +} + +bool AppInfoTablePrivate::getAllAppDesktopList(QStringList &list) +{ + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); + + if (sql.exec(cmd)) { + while (sql.next()) { + list.append(sql.value(0).toString()); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + res = false; + } + + return res; +} + +bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) +{ + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE FAVORITES!=0 ORDER BY FAVORITES"); + if (sql.exec(cmd)) { + while (sql.next()) { + list.append(sql.value(0).toString()); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + res = false; + } + return res; +} + +bool AppInfoTablePrivate::getTopAppList(QStringList &list) +{ + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE TOP!=0 ORDER BY TOP"); + + if (sql.exec(cmd)) { + while (sql.next()) { + list.append(sql.value(0).toString()); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + res = false; + } + + return res; +} + +bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) +{ + bool res(true); + if (m_database.transaction()) { + QSqlQuery sql(m_database); + QSqlQuery sqlque(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo ORDER BY LAUNCH_TIMES"); + int count = 0; + if (sql.exec(cmd)) { + while (sql.next()) { + list.append(sql.value(0).toString()); + cmd = QString("UPDATE appInfo SET TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") + .arg(++count) + .arg(sql.value(0).toString()); + if (!sqlque.exec(cmd)) { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + res = false; + break; + } + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + res = false; + } + if (!m_database.commit()) { + qWarning() << "Failed to commit !" << cmd; + m_database.rollback(); + res = false; + } + } else { + qWarning() << "Failed to start transaction mode!!!"; + res = false; + } + return res; +} + AppInfoTablePrivate::~AppInfoTablePrivate() { this->closeDataBase(); @@ -816,41 +836,6 @@ bool AppInfoTable::setAppTopState(QString &desktopfp, size_t num) return d->setAppTopState(desktopfp, num); } -bool AppInfoTable::setAppLaunchTimes(QString &desktopfp, size_t num) -{ - return d->setAppLaunchTimes(desktopfp, num); -} - -bool AppInfoTable::updateAppLaunchTimes(QString &desktopfp) -{ - return d->updateAppLaunchTimes(desktopfp); -} - -bool AppInfoTable::setAppLockState(QString &desktopfp, size_t num) -{ - return d->setAppLockState(desktopfp, num); -} - -bool AppInfoTable::getAllAppDesktopList(QStringList &list) -{ - return d->getAllAppDesktopList(list); -} - -bool AppInfoTable::getFavoritesAppList(QStringList &list) -{ - return d->getFavoritesAppList(list); -} - -bool AppInfoTable::getTopAppList(QStringList &list) -{ - return d->getTopAppList(list); -} - -bool AppInfoTable::getLaunchTimesAppList(QStringList &list) -{ - return d->getLaunchTimesAppList(list); -} - bool AppInfoTable::getAppCategory(QString &desktopfp, QString &category) { return d->getAppCategory(desktopfp, category); @@ -920,3 +905,39 @@ QString AppInfoTable::lastError() const { return d->lastError(); } + +//下面接口暂时没啥用,不外放。 +bool AppInfoTable::setAppLaunchTimes(QString &desktopfp, size_t num) +{ + return d->setAppLaunchTimes(desktopfp, num); +} + +bool AppInfoTable::updateAppLaunchTimes(QString &desktopfp) +{ + return d->updateAppLaunchTimes(desktopfp); +} + +bool AppInfoTable::setAppLockState(QString &desktopfp, size_t num) +{ + return d->setAppLockState(desktopfp, num); +} + +bool AppInfoTable::getAllAppDesktopList(QStringList &list) +{ + return d->getAllAppDesktopList(list); +} + +bool AppInfoTable::getFavoritesAppList(QStringList &list) +{ + return d->getFavoritesAppList(list); +} + +bool AppInfoTable::getTopAppList(QStringList &list) +{ + return d->getTopAppList(list); +} + +bool AppInfoTable::getLaunchTimesAppList(QStringList &list) +{ + return d->getLaunchTimesAppList(list); +} diff --git a/libsearch/appdata/app-info-table.h b/libsearch/appdata/app-info-table.h index 5ff4e5a..cc3eac4 100644 --- a/libsearch/appdata/app-info-table.h +++ b/libsearch/appdata/app-info-table.h @@ -33,33 +33,6 @@ public: */ bool setAppTopState(QString &desktopfp, size_t num); - /** - * @brief AppInfoTable::getAllAppDesktopList - * get the desktop file paths of all apps - * @param list: a stringlist include all paths - * @return bool: true if success, else false - */ - bool getAllAppDesktopList(QStringList &list); - - /** - * @brief AppInfoTable::getFavoritesAppList - * get all favorites apps - * @param list: a stringlist include all apps' paths - * @return bool: true if success, else false - */ - bool getFavoritesAppList(QStringList &list); - - /** - * @brief AppInfoTable::getTopAppList - * get all top apps - * @param list: a stringlist include all apps' paths - * @return bool: true if success, else false - */ - bool getTopAppList(QStringList &list); - - bool getLaunchTimesAppList(QStringList &list); - bool getAppCategory(QString &desktopfp, QString &category); - /** * @brief AppInfoTable::changeFavoriteAppPos * change the position of the app which is one of the Favorites Apps @@ -90,6 +63,7 @@ public: bool getAppTopState(QString &desktopfp, size_t &num); bool getAppLaunchedState(QString &desktopfp, size_t &num); bool getAppFavoriteState(QString &desktopfp, size_t &num); + bool getAppCategory(QString &desktopfp, QString &category); bool addAppShortcut2Desktop(QString &desktopfp); bool addAppShortcut2Panel(QString &desktopfp); @@ -107,10 +81,16 @@ public: QString lastError(void) const; private: + //暂不外放的接口 bool setAppLaunchTimes(QString &desktopfp, size_t num); bool setAppLockState(QString &desktopfp, size_t num); bool updateAppLaunchTimes(QString &desktopfp); + bool getAllAppDesktopList(QStringList &list); + bool getFavoritesAppList(QStringList &list); + bool getTopAppList(QStringList &list); + bool getLaunchTimesAppList(QStringList &list); +private: AppInfoTablePrivate *d; Q_SIGNALS: diff --git a/ukui-search-app-data-service/app-db-manager.cpp b/ukui-search-app-data-service/app-db-manager.cpp index 1c2ddcf..7fd4174 100644 --- a/ukui-search-app-data-service/app-db-manager.cpp +++ b/ukui-search-app-data-service/app-db-manager.cpp @@ -27,7 +27,7 @@ AppDBManager *AppDBManager::getInstance() return global_instance; } -AppDBManager::AppDBManager(QObject *parent) : QObject(parent), m_database(QSqlDatabase()) +AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDatabase()) { //链接数据库 if (openDataBase()) { @@ -46,7 +46,7 @@ AppDBManager::AppDBManager(QObject *parent) : QObject(parent), m_database(QSqlDa m_qSettings->endGroup(); //初始化数据库 - initDataBase(); + refreshDataBase(); //初始化FileSystemWatcher m_watchAppDir = new QFileSystemWatcher(this); @@ -63,23 +63,46 @@ AppDBManager::AppDBManager(QObject *parent) : QObject(parent), m_database(QSqlDa } m_watchAppDir->addPath(SNAPD_APP_DESKTOP_PATH); - //监听desktop文件所在目录,TODO:directoryChange会发多次信号,需要计时器阻塞 + //初始化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会发多次信号,使用计时器阻塞 connect(m_watchAppDir, &QFileSystemWatcher::directoryChanged, this, [ = ](const QString & path) { qDebug() << "m_watchAppDir directoryChanged:" << path; - if (m_database.transaction()) { -// this->updateAppInfoDB(); - this->updateAllData2DB(); - if (!m_database.commit()) { - qWarning() << "Failed to commit !"; - m_database.rollback(); - } else { - Q_EMIT this->finishHandleAppDB(); - } - } else { - qWarning() << "Failed to start transaction mode!!!"; + Q_EMIT this->startTimer(); + if (!m_maxProcessTimer->isActive()) { + Q_EMIT this->maxProcessTimerStart(); } }); + //计时器超时统一进行更新操作 + connect(m_timer, &QTimer::timeout, this, [ & ] { + qDebug() << "Time out! Now I can update the database!"; + Q_EMIT this->stopTimer(); + this->refreshDataBase(); + }, 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(); + this->refreshDataBase(); + }, Qt::DirectConnection); + //监控应用进程开启 connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) { QString desktopfp = ConvertWinidToDesktop::getConverter().tranIdToDesktop(id); @@ -299,6 +322,7 @@ void AppDBManager::loadDesktopFilePaths(QString path, QFileInfoList &infolist) void AppDBManager::updateAllData2DB() { + m_dbChanged = false; bool firstExec = false; QSqlQuery sql(m_database); QString cmd = "SELECT DESKTOP_FILE_PATH,MD5 FROM appInfo"; @@ -351,24 +375,28 @@ void AppDBManager::updateAllData2DB() //判断系统语言是否改变 if (m_localeChanged) { this->updateLocaleData2DB(path); + m_dbChanged = true; } dataMap.remove(path); continue; } else { //数据库有记录但md5值改变则update this->updateAppDesktopFile2DB(path); + m_dbChanged = true; dataMap.remove(path); continue; } } else { //数据库中没有记录则insert this->addAppDesktopFile2DB(path); + m_dbChanged = true; dataMap.remove(path); continue; } } //数据库为空则全部insert this->addAppDesktopFile2DB(path); + m_dbChanged = true; dataMap.remove(path); } @@ -379,6 +407,7 @@ void AppDBManager::updateAllData2DB() if (!dataMap.isEmpty()) { for (auto i = dataMap.constBegin(); i != dataMap.constEnd(); i++) { this->deleteAppDesktopFile2DB(i.key()); + m_dbChanged = true; } } } @@ -420,7 +449,12 @@ bool AppDBManager::updateLocaleData2DB(QString desktopPath) return res; } -void AppDBManager::initDataBase() +void AppDBManager::run() +{ + exec(); +} + +void AppDBManager::refreshDataBase() { if (m_database.transaction()) { // this->updateAppInfoDB(); @@ -428,6 +462,8 @@ void AppDBManager::initDataBase() 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(); } @@ -568,11 +604,37 @@ bool AppDBManager::deleteAppDesktopFile2DB(const QString &desktopfd) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("DELETE FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); + QString cmd = QString("SELECT FAVORITES, TOP FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); + + //查询要删除信息的应用是否被收藏或顶置过 + if (!sql.exec(cmd)) { + qWarning() << m_database.lastError() << cmd; + } else if (sql.next()) { + int favorites = sql.value("FAVORITES").toInt(); + int top = sql.value("TOP").toInt(); + if (favorites) { + cmd = QString("UPDATE appInfo SET FAVORITES = FAVORITES -1 WHERE FAVORITES > %1").arg(favorites); + if (!sql.exec(cmd)) { + qWarning() << "I'm going to delete item in db, fail to update the FAVORITES because:" << m_database.lastError() << cmd; + } + } + if (top) { + cmd = QString("UPDATE appInfo SET TOP = TOP -1 WHERE TOP > %1").arg(top); + if (!sql.exec(cmd)) { + qWarning() << "I'm going to delete item in db, fail to update the TOP because:" << m_database.lastError() << cmd; + } + } + } else { + qWarning() << "Fail to exec next, because" << m_database.lastError() << "while executing " << cmd; + } + + //执行删除操作 + cmd = QString("DELETE FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; res = false; } + if (res) { Q_EMIT this->appDBItemDelete(desktopfd); qDebug() << "app database delete " << desktopfd << "success!"; @@ -689,6 +751,7 @@ bool AppDBManager::updateAppLaunchTimes(QString &desktopfp) res = false; } else { AppInfoResult result; + result.desktopPath = desktopfp; result.launchTimes = launchTimes; Q_EMIT this->appDBItemUpdate(result); } diff --git a/ukui-search-app-data-service/app-db-manager.h b/ukui-search-app-data-service/app-db-manager.h index 5bd0592..8d51816 100644 --- a/ukui-search-app-data-service/app-db-manager.h +++ b/ukui-search-app-data-service/app-db-manager.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #define CONNECTION_NAME QLatin1String("ukss-appdb-connection") @@ -36,7 +38,7 @@ public: } }; -class AppDBManager : public QObject +class AppDBManager : public QThread { Q_OBJECT @@ -58,6 +60,8 @@ public: bool updateAppLaunchTimes(QString &desktopfp); void updateAllData2DB(); bool updateLocaleData2DB(QString desktopPath); +protected: + void run() override; private: explicit AppDBManager(QObject *parent = nullptr); @@ -65,7 +69,7 @@ private: void loadDesktopFilePaths(QString path, QFileInfoList &infolist); - void initDataBase(); + void refreshDataBase(); bool openDataBase(); void closeDataBase(); @@ -75,7 +79,12 @@ private: void getFilePathList(QStringList &pathList); QSettings *m_qSettings = nullptr; + bool m_localeChanged; + bool m_dbChanged; + + QTimer *m_timer = nullptr; + QTimer *m_maxProcessTimer = nullptr; QSqlDatabase m_database; @@ -131,11 +140,16 @@ private: //原本额外排除的目录,不知道额外的原因,有可能之后有问题--bjj20220621 "/usr/share/applications/screensavers" }; + Q_SIGNALS: void appDBItemUpdate(const AppInfoResult&); void appDBItemAdd(const AppInfoResult&); void appDBItemDelete(const QString&); void finishHandleAppDB(); + + void startTimer(); + void maxProcessTimerStart(); + void stopTimer(); }; } 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 a48aa90..e34dd85 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 @@ -29,13 +29,13 @@ SOURCES += \ main.cpp \ convert-winid-to-desktop.cpp \ app-db-manager.cpp \ - signal-transformer.cpp \ + signal-transformer.cpp \ ukui-search-app-data-service.cpp \ HEADERS += \ convert-winid-to-desktop.h \ app-db-manager.h \ - signal-transformer.h \ + signal-transformer.h \ ukui-search-app-data-service.h \ target.path = /usr/bin