From 40a255283083301b9503e1cbb9f0ea7db83e069a Mon Sep 17 00:00:00 2001 From: Bora Gülerman <49169566+eratoriele@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:26:10 +0300 Subject: launcher: add favorite apps (#946) * launcher: add favorite apps Favorite apps always appear above non-favorite apps Accepts regex, same logic as #920 Added the same regex logic to hidden apps Added util file may need to be relocated * addressed requested changes * fix: Renamed newly added util singleton Also added a null check to favorite icon loader in AppItem.qml * controlCenter/launcherPane: added favorite apps added icons to the app list to indicate if they are favorited/hidden marking as favorite/hidden is desabled if the other is selected * favouriteApps: renamed from favorite to favourite Also disabled favorite/hidden switch for entries added as regex * appDb: added notify and emit to favoriteApps * controlCentre/Launcher: Fixed bug with favourite switch not enabling itself when no hiddenApps exist Added a comment to explain the enabled state of the switches icon loader is now a single loader rather than two, hidden icon has priority * spelling mistakes * fixed warning * formatting fixes --- plugin/src/Caelestia/appdb.cpp | 49 +++++++++++++++++++++++++++++++++++++++++- plugin/src/Caelestia/appdb.hpp | 10 +++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) (limited to 'plugin/src/Caelestia') diff --git a/plugin/src/Caelestia/appdb.cpp b/plugin/src/Caelestia/appdb.cpp index 6e37e16..b074cf4 100644 --- a/plugin/src/Caelestia/appdb.cpp +++ b/plugin/src/Caelestia/appdb.cpp @@ -162,6 +162,39 @@ void AppDb::setEntries(const QObjectList& entries) { m_timer->start(); } +QStringList AppDb::favouriteApps() const { + return m_favouriteApps; +} + +void AppDb::setFavouriteApps(const QStringList& favApps) { + if (m_favouriteApps == favApps) { + return; + } + + m_favouriteApps = favApps; + emit favouriteAppsChanged(); + m_favouriteAppsRegex.clear(); + m_favouriteAppsRegex.reserve(m_favouriteApps.size()); + for (const QString& item : std::as_const(m_favouriteApps)) { + const QRegularExpression re(regexifyString(item)); + if (re.isValid()) { + m_favouriteAppsRegex << re; + } else { + qWarning() << "AppDb::setFavouriteApps: Regular expression is not valid: " << re.pattern(); + } + } + + emit appsChanged(); +} + +QString AppDb::regexifyString(const QString& original) const { + if (original.startsWith('^') && original.endsWith('$')) + return original; + + const QString escaped = QRegularExpression::escape(original); + return QStringLiteral("^%1$").arg(escaped); +} + QQmlListProperty AppDb::apps() { return QQmlListProperty(this, &getSortedApps()); } @@ -192,7 +225,12 @@ void AppDb::incrementFrequency(const QString& id) { QList& AppDb::getSortedApps() const { m_sortedApps = m_apps.values(); - std::sort(m_sortedApps.begin(), m_sortedApps.end(), [](AppEntry* a, AppEntry* b) { + std::sort(m_sortedApps.begin(), m_sortedApps.end(), [this](AppEntry* a, AppEntry* b) { + bool aIsFav = isFavourite(a); + bool bIsFav = isFavourite(b); + if (aIsFav != bIsFav) { + return aIsFav; + } if (a->frequency() != b->frequency()) { return a->frequency() > b->frequency(); } @@ -201,6 +239,15 @@ QList& AppDb::getSortedApps() const { return m_sortedApps; } +bool AppDb::isFavourite(const AppEntry* app) const { + for (const QRegularExpression& re : m_favouriteAppsRegex) { + if (re.match(app->id()).hasMatch()) { + return true; + } + } + return false; +} + quint32 AppDb::getFrequency(const QString& id) const { auto db = QSqlDatabase::database(m_uuid); QSqlQuery query(db); diff --git a/plugin/src/Caelestia/appdb.hpp b/plugin/src/Caelestia/appdb.hpp index 5f9b960..ce5f270 100644 --- a/plugin/src/Caelestia/appdb.hpp +++ b/plugin/src/Caelestia/appdb.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include namespace caelestia { @@ -66,6 +67,7 @@ class AppDb : public QObject { Q_PROPERTY(QString uuid READ uuid CONSTANT) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REQUIRED) Q_PROPERTY(QObjectList entries READ entries WRITE setEntries NOTIFY entriesChanged REQUIRED) + Q_PROPERTY(QStringList favouriteApps READ favouriteApps WRITE setFavouriteApps NOTIFY favouriteAppsChanged REQUIRED) Q_PROPERTY(QQmlListProperty apps READ apps NOTIFY appsChanged) public: @@ -79,6 +81,9 @@ public: [[nodiscard]] QObjectList entries() const; void setEntries(const QObjectList& entries); + [[nodiscard]] QStringList favouriteApps() const; + void setFavouriteApps(const QStringList& favApps); + [[nodiscard]] QQmlListProperty apps(); Q_INVOKABLE void incrementFrequency(const QString& id); @@ -86,6 +91,7 @@ public: signals: void pathChanged(); void entriesChanged(); + void favouriteAppsChanged(); void appsChanged(); private: @@ -94,10 +100,14 @@ private: const QString m_uuid; QString m_path; QObjectList m_entries; + QStringList m_favouriteApps; // unedited string list from qml + QList m_favouriteAppsRegex; // pre-regexified m_favouriteApps list QHash m_apps; mutable QList m_sortedApps; + QString regexifyString(const QString& original) const; QList& getSortedApps() const; + bool isFavourite(const AppEntry* app) const; quint32 getFrequency(const QString& id) const; void updateAppFrequencies(); void updateApps(); -- cgit v1.2.3-freya