Merge branch '0627ukss' into 'ukss-dev'
Add interfaces for changing position of top&favorites apps.Add update signal.Modify update logic.Adjust the struct of app-db-manager and app-info-table. See merge request kylin-desktop/ukui-search!340
This commit is contained in:
commit
aea548ad74
|
@ -0,0 +1,51 @@
|
|||
#ifndef APPDBCOMMON_H
|
||||
#define APPDBCOMMON_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QMetaType>
|
||||
#include <QDBusArgument>
|
||||
|
||||
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 favorite;
|
||||
int launchTimes;
|
||||
int lock;
|
||||
|
||||
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.favorite << 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.favorite >> infoResult.launchTimes >> infoResult.lock;
|
||||
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(UkuiSearch::AppInfoResult)
|
||||
|
||||
#endif // APPDBCOMMON_H
|
|
@ -1,10 +1,13 @@
|
|||
#ifndef APPINFOTABLEPRIVATE_H
|
||||
#define APPINFOTABLEPRIVATE_H
|
||||
|
||||
#include "app-info-table.h"
|
||||
#include <QObject>
|
||||
#include <QDBusInterface>
|
||||
#include <QSqlDatabase>
|
||||
#include <app-info-table.h>
|
||||
|
||||
namespace UkuiSearch {
|
||||
|
||||
class AppInfoTablePrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -15,44 +18,61 @@ 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 getAllAppDesktopList(QStringList &list);
|
||||
bool getFavoritesAppList(QStringList &list);
|
||||
bool getTopAppList(QStringList &list);
|
||||
bool getLaunchTimesAppList(QStringList &list);
|
||||
bool getAppCategory(QString &desktopfp, QString &category);
|
||||
//拖动改变置顶和收藏应用位置
|
||||
bool changeFavoriteAppPos(const QString &desktopfp, size_t pos);
|
||||
bool changeTopAppPos(const QString &desktopfp, size_t pos);
|
||||
|
||||
bool getAppInfoResults(QVector<AppInfoTable::AppInfoResult> &appInfoResults);
|
||||
//获取所有应用信息并存到一个结构体中
|
||||
bool getAppInfoResults(QVector<AppInfoResult> &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 getAppCategory(QString &desktopfp, QString &category);
|
||||
|
||||
//添加快捷方式
|
||||
bool addAppShortcut2Desktop(QString &desktopfp);
|
||||
bool addAppShortcut2Panel(QString &desktopfp);
|
||||
|
||||
bool getInstallAppMap(QMultiMap<QString, QStringList> &installAppMap);
|
||||
//搜索接口
|
||||
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();
|
||||
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<AppInfoResult> results);
|
||||
void sendAppDBItemsAdd(QVector<AppInfoResult> results);
|
||||
void sendAppDBItemsDelete(QStringList desktopfps);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,59 +2,68 @@
|
|||
#define APPINFOTABLE_H
|
||||
|
||||
#include <QObject>
|
||||
#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);
|
||||
bool setAppTopState(QString &desktopfp, size_t num);
|
||||
|
||||
bool getAllAppDesktopList(QStringList &list);
|
||||
bool getFavoritesAppList(QStringList &list);
|
||||
bool getTopAppList(QStringList &list);
|
||||
bool getLaunchTimesAppList(QStringList &list);
|
||||
bool getAppCategory(QString &desktopfp, QString &category);
|
||||
|
||||
/**
|
||||
* @brief getAppInfoResults
|
||||
* @param appInfoResults
|
||||
* @return
|
||||
* @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 getAppInfoResults(QVector<AppInfoTable::AppInfoResult> &appInfoResults);
|
||||
bool setAppTopState(QString &desktopfp, size_t num);
|
||||
|
||||
/**
|
||||
* @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 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<AppInfoResult> &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 getAppCategory(QString &desktopfp, QString &category);
|
||||
|
||||
bool addAppShortcut2Desktop(QString &desktopfp);
|
||||
bool addAppShortcut2Panel(QString &desktopfp);
|
||||
|
@ -65,20 +74,30 @@ 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;
|
||||
|
||||
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:
|
||||
void DBOpenFailed();
|
||||
|
||||
void appDBItems2BUpdate(QVector<AppInfoResult>);
|
||||
void appDBItems2BAdd(QVector<AppInfoResult>);
|
||||
void appDBItems2BDelete(QStringList);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ SOURCES += \
|
|||
libsearch.cpp
|
||||
|
||||
HEADERS += \
|
||||
app-db-common.h \
|
||||
common.h \
|
||||
file-utils.h \
|
||||
global-settings.h \
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef APPDBCOMMONDEFINES_H
|
||||
#define APPDBCOMMONDEFINES_H
|
||||
#include <QDir>
|
||||
|
||||
namespace UkuiSearch {
|
||||
|
||||
#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/"
|
||||
#define APP_DATABASE_NAME "app-info.db"
|
||||
|
||||
}
|
||||
#endif // APPDBCOMMONDEFINES_H
|
|
@ -1,10 +1,11 @@
|
|||
#include "app-db-manager.h"
|
||||
#include "file-utils.h"
|
||||
#include "convert-winid-to-desktop.h"
|
||||
|
||||
#include <qt5xdg/XdgDesktopFile>
|
||||
#include <QMutexLocker>
|
||||
#include <QCryptographicHash>
|
||||
#include <QFile>
|
||||
#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/"
|
||||
|
@ -26,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()) {
|
||||
|
@ -45,7 +46,7 @@ AppDBManager::AppDBManager(QObject *parent) : QObject(parent), m_database(QSqlDa
|
|||
m_qSettings->endGroup();
|
||||
|
||||
//初始化数据库
|
||||
initDataBase();
|
||||
refreshDataBase();
|
||||
|
||||
//初始化FileSystemWatcher
|
||||
m_watchAppDir = new QFileSystemWatcher(this);
|
||||
|
@ -62,21 +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 {
|
||||
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);
|
||||
|
@ -111,7 +137,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")//应用分类
|
||||
|
@ -296,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";
|
||||
|
@ -348,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);
|
||||
}
|
||||
|
||||
|
@ -376,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +438,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;
|
||||
|
@ -413,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();
|
||||
|
@ -421,6 +462,10 @@ 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();
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Failed to start transaction mode!!!";
|
||||
|
@ -482,11 +527,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 +569,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 +586,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!";
|
||||
|
@ -552,12 +604,39 @@ 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!";
|
||||
} else {
|
||||
qDebug() << "app database delete " << desktopfd << "failed!";
|
||||
|
@ -612,7 +691,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 +718,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 +740,20 @@ 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.desktopPath = desktopfp;
|
||||
result.launchTimes = launchTimes;
|
||||
Q_EMIT this->appDBItemUpdate(result);
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Failed to exec next!" << cmd;
|
||||
|
@ -675,6 +767,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!!!";
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef APPDBMANAGER_H
|
||||
#define APPDBMANAGER_H
|
||||
|
||||
#include "app-db-common.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
|
@ -12,7 +14,8 @@
|
|||
#include <QFileSystemWatcher>
|
||||
#include <QMutex>
|
||||
#include <QSettings>
|
||||
#include "app-db-common-defines.h"
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
#define CONNECTION_NAME QLatin1String("ukss-appdb-connection")
|
||||
|
||||
|
@ -35,7 +38,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class AppDBManager : public QObject
|
||||
class AppDBManager : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -57,6 +60,8 @@ public:
|
|||
bool updateAppLaunchTimes(QString &desktopfp);
|
||||
void updateAllData2DB();
|
||||
bool updateLocaleData2DB(QString desktopPath);
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
explicit AppDBManager(QObject *parent = nullptr);
|
||||
|
@ -64,7 +69,7 @@ private:
|
|||
|
||||
void loadDesktopFilePaths(QString path, QFileInfoList &infolist);
|
||||
|
||||
void initDataBase();
|
||||
void refreshDataBase();
|
||||
bool openDataBase();
|
||||
void closeDataBase();
|
||||
|
||||
|
@ -74,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,6 +141,15 @@ private:
|
|||
"/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();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef SIGNALTRANSFORMER_H
|
||||
#define SIGNALTRANSFORMER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusInterface>
|
||||
#include <QMutexLocker>
|
||||
#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<AppInfoResult> m_items2BUpdate;
|
||||
QVector<AppInfoResult> m_items2BInsert;
|
||||
QStringList m_items2BDelete;
|
||||
|
||||
Q_SIGNALS:
|
||||
void appDBItemsUpdate(QVector<AppInfoResult>);
|
||||
void appDBItemsAdd(QVector<AppInfoResult>);
|
||||
void appDBItemsDelete(QStringList);
|
||||
};
|
||||
|
||||
#endif // SIGNALTRANSFORMER_H
|
|
@ -1,6 +1,11 @@
|
|||
#include <QDebug>
|
||||
#include "ukui-search-app-data-service.h"
|
||||
#include "app-db-manager.h"
|
||||
#include "signal-transformer.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMetaType>
|
||||
#include <QDBusError>
|
||||
#include <QDebug>
|
||||
|
||||
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>("AppInfoResult");
|
||||
qRegisterMetaType<QVector<AppInfoResult>>("QVector<AppInfoResult>");
|
||||
|
||||
qDBusRegisterMetaType<AppInfoResult>();
|
||||
qDBusRegisterMetaType<QVector<AppInfoResult>>();
|
||||
|
||||
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);
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue