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