添加应用最近安装功能

This commit is contained in:
gjq 2023-04-17 17:23:08 +08:00
parent 0c317e9a41
commit 24ca01368f
12 changed files with 132 additions and 16 deletions

View File

@ -33,7 +33,7 @@ MouseArea {
Loader { Loader {
id: tag id: tag
property bool recentInsatlled: false property bool recentInsatlled: (recentInstall === undefined) ? false : recentInstall
property bool fixToTop: (toTop !== undefined) && (toTop !== 0) property bool fixToTop: (toTop !== undefined) && (toTop !== 0)
visible: fixToTop || recentInsatlled visible: fixToTop || recentInsatlled
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter

View File

@ -46,6 +46,7 @@ Item {
property string name: model.name property string name: model.name
property string icon: model.icon property string icon: model.icon
property int toTop: model.top property int toTop: model.top
property bool recentInstall: model.recentInstall
sourceComponent: { sourceComponent: {
if (type === DataType.Normal) { if (type === DataType.Normal) {
return appItem; return appItem;
@ -72,6 +73,9 @@ Item {
} }
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
appManager.launchApp(id); appManager.launchApp(id);
if (recentInstall) {
appManager.appLaunched(id);
}
return; return;
} }
} }

View File

@ -48,6 +48,7 @@ public Q_SLOTS:
void fixToFavoriteSlot(const QString &path, const int &num); void fixToFavoriteSlot(const QString &path, const int &num);
void changedFavoriteOrderSlot(const QString &path, const int &num); void changedFavoriteOrderSlot(const QString &path, const int &num);
void fixToTopSlot(const QString &path, const int &num); void fixToTopSlot(const QString &path, const int &num);
void setAppLaunched(const QString &path);
private: private:
void updateFavoriteApps(); void updateFavoriteApps();
@ -93,8 +94,11 @@ void AppDataWorker::initAppData()
<< UkuiSearch::ApplicationProperty::Property::LocalName << UkuiSearch::ApplicationProperty::Property::LocalName
<< UkuiSearch::ApplicationProperty::Property::Category << UkuiSearch::ApplicationProperty::Property::Category
<< UkuiSearch::ApplicationProperty::Property::FirstLetterAll << UkuiSearch::ApplicationProperty::Property::FirstLetterAll
<< UkuiSearch::ApplicationProperty::Property::DontDisplay; << UkuiSearch::ApplicationProperty::Property::DontDisplay
<< UkuiSearch::ApplicationProperty::Property::InsertTime
<< UkuiSearch::ApplicationProperty::Property::Launched;
m_appPropertyMap.insert(UkuiSearch::ApplicationProperty::Property::DontDisplay, 0); m_appPropertyMap.insert(UkuiSearch::ApplicationProperty::Property::DontDisplay, 0);
m_appPropertyMap.insert(UkuiSearch::ApplicationProperty::Property::AutoStart, 0);
UkuiSearch::ApplicationInfoMap appInfos = m_applicationInfo->getInfo(m_appProperties, m_appPropertyMap); UkuiSearch::ApplicationInfoMap appInfos = m_applicationInfo->getInfo(m_appProperties, m_appPropertyMap);
@ -172,6 +176,8 @@ void AppDataWorker::addInfoToApp(const UkuiSearch::ApplicationPropertyMap &info,
app.setName(info.value(UkuiSearch::ApplicationProperty::Property::LocalName).toString()); app.setName(info.value(UkuiSearch::ApplicationProperty::Property::LocalName).toString());
app.setCategory(info.value(UkuiSearch::ApplicationProperty::Property::Category).toString()); app.setCategory(info.value(UkuiSearch::ApplicationProperty::Property::Category).toString());
app.setFirstLetter(info.value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString()); app.setFirstLetter(info.value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString());
app.setInsertTime(info.value(UkuiSearch::ApplicationProperty::Property::InsertTime).toString());
app.setLaunched(info.value(UkuiSearch::ApplicationProperty::Property::Launched).toInt());
} }
void AppDataWorker::onAppUpdated(const UkuiSearch::ApplicationInfoMap &infos) void AppDataWorker::onAppUpdated(const UkuiSearch::ApplicationInfoMap &infos)
@ -239,6 +245,12 @@ void AppDataWorker::updateApps(const UkuiSearch::ApplicationInfoMap &infos, QLis
case UkuiSearch::ApplicationProperty::Property::FirstLetterAll: case UkuiSearch::ApplicationProperty::Property::FirstLetterAll:
app.setFirstLetter(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString()); app.setFirstLetter(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString());
break; break;
case UkuiSearch::ApplicationProperty::Property::InsertTime:
app.setInsertTime(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::InsertTime).toString());
break;
case UkuiSearch::ApplicationProperty::Property::Launched:
app.setLaunched(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::Launched).toInt());
break;
default: default:
break; break;
} }
@ -297,6 +309,11 @@ void AppDataWorker::fixToTopSlot(const QString &path, const int &num)
} }
} }
void AppDataWorker::setAppLaunched(const QString &path)
{
m_applicationInfo->setAppLaunchedState(path);
}
void AppDataWorker::removeApps(QStringList &appIdList, QStringList &removedIdList) void AppDataWorker::removeApps(QStringList &appIdList, QStringList &removedIdList)
{ {
QMutexLocker locker(&m_appManager->m_mutex); QMutexLocker locker(&m_appManager->m_mutex);
@ -328,6 +345,7 @@ AppDataManager::AppDataManager()
connect(this, &AppDataManager::fixToFavoriteSignal, appDataWorker, &AppDataWorker::fixToFavoriteSlot); connect(this, &AppDataManager::fixToFavoriteSignal, appDataWorker, &AppDataWorker::fixToFavoriteSlot);
connect(this, &AppDataManager::changedFavoriteOrderSignal, appDataWorker, &AppDataWorker::changedFavoriteOrderSlot); connect(this, &AppDataManager::changedFavoriteOrderSignal, appDataWorker, &AppDataWorker::changedFavoriteOrderSlot);
connect(this, &AppDataManager::fixToTop, appDataWorker, &AppDataWorker::fixToTopSlot); connect(this, &AppDataManager::fixToTop, appDataWorker, &AppDataWorker::fixToTopSlot);
connect(this, &AppDataManager::appLaunch, appDataWorker, &AppDataWorker::setAppLaunched);
m_workerThread.start(); m_workerThread.start();
} }

View File

@ -58,6 +58,7 @@ Q_SIGNALS:
void fixToFavoriteSignal(const QString &path, const int &num); void fixToFavoriteSignal(const QString &path, const int &num);
void changedFavoriteOrderSignal(const QString &path, const int &num); void changedFavoriteOrderSignal(const QString &path, const int &num);
void fixToTop(const QString &path, const int &num); void fixToTop(const QString &path, const int &num);
void appLaunch(const QString &path);
private: private:
AppDataManager(); AppDataManager();

View File

@ -21,6 +21,7 @@
#include "app-folder-helper.h" #include "app-folder-helper.h"
#include <QDebug> #include <QDebug>
#include <QDateTime>
namespace UkuiMenu { namespace UkuiMenu {
@ -92,23 +93,15 @@ void AllAppDataProvider::reloadAppData()
return; return;
} }
for (const auto &app : apps) { for (auto &app : apps) {
if (AppFolderHelper::instance()->containApp(app.id())) { if (AppFolderHelper::instance()->containApp(app.id())) {
continue; continue;
} }
setRecentState(app);
appData.append(app); appData.append(app);
} }
std::sort(appData.begin(), appData.end(), [](const DataEntity &a, const DataEntity &b) { std::sort(appData.begin(), appData.end(), appDataSort);
if (a.top() == 0) {
return (a.top() == b.top()) ? (a.launchTimes() > b.launchTimes()) : (a.top() > b.top());
} else if (b.top() == 0) {
return a.top() > b.top();
} else {
return a.top() < b.top();
}
});
m_appData.swap(appData); m_appData.swap(appData);
} }
@ -143,6 +136,43 @@ void AllAppDataProvider::mergeData(QVector<DataEntity> &data)
data.append(m_appData); data.append(m_appData);
} }
bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b)
{
if ((a.top() != 0) && (b.top() != 0)) {
return a.top() < b.top();
} else if ((a.top() == 0) && (b.top() == 0)) {
if (a.isRecentInstall()) {
if (b.isRecentInstall()) {
return QDateTime::fromString(a.insertTime(), "yyyy-MM-dd hh:mm:ss")
> QDateTime::fromString(b.insertTime(), "yyyy-MM-dd hh:mm:ss");
} else {
return true;
}
} else if (b.isRecentInstall()) {
return false;
} else {
return a.launchTimes() > b.launchTimes();
}
} else {
return a.top() > b.top();
}
}
void AllAppDataProvider::setRecentState(DataEntity &app)
{
if (app.launched() == 0) {
QDateTime installTime = QDateTime::fromString(app.insertTime(), "yyyy-MM-dd hh:mm:ss");
if (installTime.isValid()) {
int appTime = installTime.secsTo(QDateTime::currentDateTime());
if ((appTime >= 0 ) && (appTime <= 3600*48)) {
app.setRecentInstall(true);
return;
}
}
}
app.setRecentInstall(false);
}
void AllAppDataProvider::sendData() void AllAppDataProvider::sendData()
{ {
QVector<DataEntity> data; QVector<DataEntity> data;
@ -159,7 +189,11 @@ void AllAppDataProvider::onAppAdded(const QList<DataEntity>& apps)
{ {
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
m_appData.append(apps.toVector()); for (auto app : apps) {
setRecentState(app);
m_appData.append(app);
}
std::sort(m_appData.begin(), m_appData.end(), appDataSort);
} }
sendData(); sendData();
} }
@ -167,6 +201,7 @@ void AllAppDataProvider::onAppAdded(const QList<DataEntity>& apps)
void AllAppDataProvider::onAppDeleted(QStringList idList) void AllAppDataProvider::onAppDeleted(QStringList idList)
{ {
removeApps(idList); removeApps(idList);
reloadFolderData();
sendData(); sendData();
} }

View File

@ -52,6 +52,8 @@ private:
void reloadAppData(); void reloadAppData();
void reloadFolderData(); void reloadFolderData();
void mergeData(QVector<DataEntity> &data); void mergeData(QVector<DataEntity> &data);
static bool appDataSort(const DataEntity &a, const DataEntity &b);
static void setRecentState(DataEntity &app);
private: private:
QMutex m_mutex; QMutex m_mutex;

View File

@ -28,6 +28,8 @@ public:
: type(type), name(std::move(name)), icon(std::move(icon)), comment(std::move(comment)), extraData(std::move(extraData)) {} : type(type), name(std::move(name)), icon(std::move(icon)), comment(std::move(comment)), extraData(std::move(extraData)) {}
bool lock{false}; // 应用锁定 bool lock{false}; // 应用锁定
bool recentInstall{false};
int launched{0}; // 是否启动过
int top{0}; // 置顶状态及序号 int top{0}; // 置顶状态及序号
int favorite{0}; // 收藏状态及序号 int favorite{0}; // 收藏状态及序号
int launchTimes{0}; // 启动次数 int launchTimes{0}; // 启动次数
@ -39,6 +41,7 @@ public:
QString firstLetter; QString firstLetter;
QString comment; // 应用描述 QString comment; // 应用描述
QString extraData; // 额外的数据 QString extraData; // 额外的数据
QString insertTime; //安装的时间
}; };
DataEntity::DataEntity() : d(new DataEntityPrivate) {} DataEntity::DataEntity() : d(new DataEntityPrivate) {}
@ -69,6 +72,26 @@ void DataEntity::setLock(bool lock)
d->lock = lock; d->lock = lock;
} }
bool DataEntity::isRecentInstall() const
{
return d->recentInstall;
}
void DataEntity::setRecentInstall(bool recentInsatll)
{
d->recentInstall = recentInsatll;
}
int DataEntity::launched() const
{
return d->launched;
}
void DataEntity::setLaunched(int launched)
{
d->launched = launched;
}
int DataEntity::favorite() const int DataEntity::favorite() const
{ {
return d->favorite; return d->favorite;
@ -89,6 +112,16 @@ void DataEntity::setLaunchTimes(int launchTimes)
d->launchTimes = launchTimes; d->launchTimes = launchTimes;
} }
QString DataEntity::insertTime() const
{
return d->insertTime;
}
void DataEntity::setInsertTime(const QString &insertTime)
{
d->insertTime = insertTime;
}
QString DataEntity::id() const QString DataEntity::id() const
{ {
return d->id; return d->id;
@ -179,6 +212,7 @@ QHash<int, QByteArray> DataEntity::AppRoleNames()
names.insert(DataEntity::Comment, "comment"); names.insert(DataEntity::Comment, "comment");
names.insert(DataEntity::ExtraData, "extraData"); names.insert(DataEntity::ExtraData, "extraData");
names.insert(DataEntity::Top, "top"); names.insert(DataEntity::Top, "top");
names.insert(DataEntity::RecentInstall, "recentInstall");
return names; return names;
} }

View File

@ -58,7 +58,8 @@ public:
Name, Name,
Comment, Comment,
ExtraData, ExtraData,
Top Top,
RecentInstall
}; };
DataEntity(); DataEntity();
DataEntity(DataType::Type type, const QString& name, const QString& icon, const QString& comment, const QString& extraData); DataEntity(DataType::Type type, const QString& name, const QString& icon, const QString& comment, const QString& extraData);
@ -76,12 +77,21 @@ public:
bool isLock() const; bool isLock() const;
void setLock(bool lock); void setLock(bool lock);
bool isRecentInstall() const;
void setRecentInstall(bool recentInsatll);
int launched() const;
void setLaunched(int launched);
int favorite() const; int favorite() const;
void setFavorite(int favorite); void setFavorite(int favorite);
int launchTimes() const; int launchTimes() const;
void setLaunchTimes(int launchTimes); void setLaunchTimes(int launchTimes);
QString insertTime() const;
void setInsertTime(const QString& insertTime);
QString id() const; QString id() const;
void setId(const QString& id); void setId(const QString& id);

View File

@ -63,6 +63,11 @@ QVariant AppModel::data(const QModelIndex &index, int role) const
return m_apps.at(i).top(); return m_apps.at(i).top();
} }
return 0; return 0;
case DataEntity::RecentInstall:
if (DataProviderManager::instance()->activatedProvider() == "all") {
return m_apps.at(i).isRecentInstall();
}
return false;
default: default:
break; break;
} }

View File

@ -61,7 +61,7 @@ private:
QVector<DataEntity> m_apps; QVector<DataEntity> m_apps;
Q_SIGNALS: Q_SIGNALS:
Q_INVOKABLE void renameText(QString id); void renameText(QString id);
}; };
} // UkuiMenu } // UkuiMenu

View File

@ -18,6 +18,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include "app-manager.h" #include "app-manager.h"
#include "app-data-manager.h"
#include <QDebug> #include <QDebug>
#include <QDBusReply> #include <QDBusReply>
@ -76,6 +77,11 @@ bool AppManager::launchBinaryApp(const QString &app, const QString &args)
return QProcess::startDetached(cmd); return QProcess::startDetached(cmd);
} }
void AppManager::appLaunched(const QString &desktopFilePath)
{
AppDataManager::instance()->appLaunch(desktopFilePath);
}
bool AppManager::launchAppWithDBus(const QString &app) bool AppManager::launchAppWithDBus(const QString &app)
{ {
if (!m_appManagerDbusInterface) { if (!m_appManagerDbusInterface) {

View File

@ -34,6 +34,7 @@ public:
Q_INVOKABLE bool launchApp(const QString &desktopFilePath); Q_INVOKABLE bool launchApp(const QString &desktopFilePath);
Q_INVOKABLE bool launchBinaryApp(const QString &app, const QString &args = QString()); Q_INVOKABLE bool launchBinaryApp(const QString &app, const QString &args = QString());
Q_INVOKABLE void appLaunched(const QString &desktopFilePath);
private: private:
explicit AppManager(QObject *parent = nullptr); explicit AppManager(QObject *parent = nullptr);