2014-10-28 12:27:54 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License version 2,
|
|
|
|
|
* or (at your option) any later version, as published by the Free
|
|
|
|
|
* Software Foundation
|
|
|
|
|
*
|
|
|
|
|
* 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, write to the
|
|
|
|
|
* Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Self
|
|
|
|
|
#include "applicationlistmodel.h"
|
|
|
|
|
|
|
|
|
|
// Qt
|
|
|
|
|
#include <QByteArray>
|
|
|
|
|
#include <QModelIndex>
|
2014-11-05 21:02:40 +00:00
|
|
|
#include <QProcess>
|
2020-05-10 16:07:36 +00:00
|
|
|
#include <QDebug>
|
2014-10-28 12:27:54 +00:00
|
|
|
|
|
|
|
|
// KDE
|
2020-05-10 16:07:36 +00:00
|
|
|
#include <KIO/ApplicationLauncherJob>
|
|
|
|
|
#include <KNotificationJobUiDelegate>
|
2014-10-28 12:27:54 +00:00
|
|
|
#include <KService>
|
|
|
|
|
#include <KServiceGroup>
|
2015-06-16 03:08:12 +00:00
|
|
|
#include <KSharedConfig>
|
2015-03-18 13:57:54 +00:00
|
|
|
#include <KSycoca>
|
2014-10-28 12:27:54 +00:00
|
|
|
#include <KSycocaEntry>
|
|
|
|
|
|
2020-03-20 00:08:59 +00:00
|
|
|
constexpr int MAX_FAVOURITES = 5;
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
2019-09-18 11:55:07 +00:00
|
|
|
: QAbstractListModel(parent),
|
2020-03-20 22:47:18 +00:00
|
|
|
m_homeScreen(parent),
|
|
|
|
|
m_startupInfo(new KStartupInfo(0, this))
|
2014-10-28 12:27:54 +00:00
|
|
|
{
|
2019-11-20 10:49:50 +00:00
|
|
|
connect(KSycoca::self(), qOverload<const QStringList &>(&KSycoca::databaseChanged),
|
|
|
|
|
this, &ApplicationListModel::sycocaDbChanged);
|
2019-09-18 11:55:07 +00:00
|
|
|
|
2020-03-20 22:47:18 +00:00
|
|
|
connect(m_startupInfo, &KStartupInfo::gotRemoveStartup,
|
|
|
|
|
this, &ApplicationListModel::applicationExited);
|
|
|
|
|
|
|
|
|
|
connect(m_startupInfo, &KStartupInfo::gotNewStartup,
|
|
|
|
|
this, [=](const KStartupInfoId &, const KStartupInfoData &data) {
|
|
|
|
|
applicationStarted(data.name(), data.icon());
|
|
|
|
|
});
|
|
|
|
|
|
2019-09-16 17:13:52 +00:00
|
|
|
loadSettings();
|
2020-03-20 22:47:18 +00:00
|
|
|
|
|
|
|
|
// Debug
|
2020-05-28 13:58:18 +00:00
|
|
|
connect(this, &ApplicationListModel::applicationStarted, this, [=](const QString &name, const QString &icon) {
|
2020-03-20 22:47:18 +00:00
|
|
|
qDebug() << "Opening startup feedback for" << name << icon;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(this, &ApplicationListModel::applicationExited, this, []() {
|
|
|
|
|
qDebug() << "Removing startup feedback";
|
2020-05-28 13:58:18 +00:00
|
|
|
});
|
|
|
|
|
|
2019-09-16 17:13:52 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-20 00:08:59 +00:00
|
|
|
ApplicationListModel::~ApplicationListModel() = default;
|
2019-09-16 17:13:52 +00:00
|
|
|
|
|
|
|
|
void ApplicationListModel::loadSettings()
|
|
|
|
|
{
|
2019-09-04 16:39:31 +00:00
|
|
|
m_favorites = m_homeScreen->config().readEntry("Favorites", QStringList());
|
2019-12-06 21:04:33 +00:00
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
2020-02-06 15:46:14 +00:00
|
|
|
const auto di = m_homeScreen->config().readEntry("DesktopItems", QStringList());
|
|
|
|
|
m_desktopItems = QSet<QString>(di.begin(), di.end());
|
2019-12-06 21:04:33 +00:00
|
|
|
#else
|
2019-09-04 16:39:31 +00:00
|
|
|
m_desktopItems = m_homeScreen->config().readEntry("DesktopItems", QStringList()).toSet();
|
2019-12-06 21:04:33 +00:00
|
|
|
#endif
|
2019-09-04 16:39:31 +00:00
|
|
|
m_appOrder = m_homeScreen->config().readEntry("AppOrder", QStringList());
|
2020-03-20 00:08:59 +00:00
|
|
|
m_maxFavoriteCount = m_homeScreen->config().readEntry("MaxFavoriteCount", MAX_FAVOURITES);
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
int i = 0;
|
2019-11-20 08:31:54 +00:00
|
|
|
for (const QString &app : qAsConst(m_appOrder)) {
|
2019-09-04 16:39:31 +00:00
|
|
|
m_appPositions[app] = i;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
loadApplications();
|
2014-10-28 12:27:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
|
|
|
|
{
|
2020-03-20 00:58:46 +00:00
|
|
|
return {
|
|
|
|
|
{ApplicationNameRole, QByteArrayLiteral("applicationName")},
|
|
|
|
|
{ApplicationIconRole, QByteArrayLiteral("applicationIcon")},
|
|
|
|
|
{ApplicationStorageIdRole, QByteArrayLiteral("applicationStorageId")},
|
|
|
|
|
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
|
|
|
|
|
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
|
|
|
|
|
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
|
|
|
|
|
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")}
|
|
|
|
|
};
|
2015-03-18 13:34:05 +00:00
|
|
|
}
|
2014-10-28 12:27:54 +00:00
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
void ApplicationListModel::sycocaDbChanged(const QStringList &changes)
|
|
|
|
|
{
|
2020-03-20 00:08:59 +00:00
|
|
|
if (!changes.contains(QStringLiteral("apps")) && !changes.contains(QStringLiteral("xdgdata-apps"))) {
|
2019-09-18 11:55:07 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_applicationList.clear();
|
|
|
|
|
|
|
|
|
|
loadApplications();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool appNameLessThan(const ApplicationData &a1, const ApplicationData &a2)
|
|
|
|
|
{
|
|
|
|
|
return a1.name.toLower() < a2.name.toLower();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplicationListModel::loadApplications()
|
|
|
|
|
{
|
2020-03-20 00:08:59 +00:00
|
|
|
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
2019-09-18 11:55:07 +00:00
|
|
|
auto blgroup = KConfigGroup(cfg, QStringLiteral("Applications"));
|
|
|
|
|
|
|
|
|
|
// This is only temporary to get a clue what those apps' desktop files are called
|
|
|
|
|
// I'll remove it once I've done a blacklist
|
|
|
|
|
QStringList bl;
|
|
|
|
|
|
|
|
|
|
QStringList blacklist = blgroup.readEntry("blacklist", QStringList());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
beginResetModel();
|
|
|
|
|
|
|
|
|
|
m_applicationList.clear();
|
|
|
|
|
|
|
|
|
|
KServiceGroup::Ptr group = KServiceGroup::root();
|
2020-03-20 22:47:18 +00:00
|
|
|
if (!group || !group->isValid())
|
|
|
|
|
return;
|
2019-09-18 11:55:07 +00:00
|
|
|
KServiceGroup::List subGroupList = group->entries(true);
|
|
|
|
|
|
|
|
|
|
QMap<int, ApplicationData> orderedList;
|
|
|
|
|
QList<ApplicationData> unorderedList;
|
|
|
|
|
|
|
|
|
|
// Iterate over all entries in the group
|
|
|
|
|
while (!subGroupList.isEmpty()) {
|
|
|
|
|
KSycocaEntry::Ptr groupEntry = subGroupList.first();
|
|
|
|
|
subGroupList.pop_front();
|
|
|
|
|
|
|
|
|
|
if (groupEntry->isType(KST_KServiceGroup)) {
|
2020-03-20 09:10:09 +00:00
|
|
|
KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(groupEntry.data()));
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
if (!serviceGroup->noDisplay()) {
|
|
|
|
|
KServiceGroup::List entryGroupList = serviceGroup->entries(true);
|
|
|
|
|
|
|
|
|
|
for(KServiceGroup::List::ConstIterator it = entryGroupList.constBegin(); it != entryGroupList.constEnd(); it++) {
|
|
|
|
|
KSycocaEntry::Ptr entry = (*it);
|
|
|
|
|
|
|
|
|
|
if (entry->isType(KST_KServiceGroup)) {
|
2020-03-20 09:10:09 +00:00
|
|
|
KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(entry.data()));
|
2019-09-18 11:55:07 +00:00
|
|
|
subGroupList << serviceGroup;
|
|
|
|
|
|
2020-03-20 00:08:59 +00:00
|
|
|
} else if (entry->property(QStringLiteral("Exec")).isValid()) {
|
2020-03-20 09:10:09 +00:00
|
|
|
KService::Ptr service(static_cast<KService *>(entry.data()));
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
if (service->isApplication() &&
|
|
|
|
|
!blacklist.contains(service->desktopEntryName()) &&
|
|
|
|
|
service->showOnCurrentPlatform() &&
|
2020-03-20 00:08:59 +00:00
|
|
|
!service->property(QStringLiteral("Terminal"), QVariant::Bool).toBool()) {
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
bl << service->desktopEntryName();
|
|
|
|
|
|
|
|
|
|
ApplicationData data;
|
|
|
|
|
data.name = service->name();
|
|
|
|
|
data.icon = service->icon();
|
|
|
|
|
data.storageId = service->storageId();
|
|
|
|
|
data.entryPath = service->exec();
|
2020-03-20 00:08:59 +00:00
|
|
|
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
if (m_favorites.contains(data.storageId)) {
|
2020-03-21 01:59:49 +00:00
|
|
|
data.location = Favorites;
|
2019-09-18 11:55:07 +00:00
|
|
|
} else if (m_desktopItems.contains(data.storageId)) {
|
2020-03-21 01:59:49 +00:00
|
|
|
data.location = Desktop;
|
2019-09-18 11:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto it = m_appPositions.constFind(service->storageId());
|
|
|
|
|
if (it != m_appPositions.constEnd()) {
|
|
|
|
|
orderedList[*it] = data;
|
|
|
|
|
} else {
|
|
|
|
|
unorderedList << data;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blgroup.writeEntry("allapps", bl);
|
|
|
|
|
blgroup.writeEntry("blacklist", blacklist);
|
|
|
|
|
cfg->sync();
|
|
|
|
|
|
|
|
|
|
std::sort(unorderedList.begin(), unorderedList.end(), appNameLessThan);
|
|
|
|
|
m_applicationList << orderedList.values();
|
|
|
|
|
m_applicationList << unorderedList;
|
|
|
|
|
|
|
|
|
|
endResetModel();
|
|
|
|
|
emit countChanged();
|
|
|
|
|
}
|
2014-10-28 12:27:54 +00:00
|
|
|
|
|
|
|
|
QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid()) {
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (role) {
|
2019-09-18 11:55:07 +00:00
|
|
|
case Qt::DisplayRole:
|
|
|
|
|
case ApplicationNameRole:
|
|
|
|
|
return m_applicationList.at(index.row()).name;
|
|
|
|
|
case ApplicationIconRole:
|
|
|
|
|
return m_applicationList.at(index.row()).icon;
|
|
|
|
|
case ApplicationStorageIdRole:
|
|
|
|
|
return m_applicationList.at(index.row()).storageId;
|
|
|
|
|
case ApplicationEntryPathRole:
|
|
|
|
|
return m_applicationList.at(index.row()).entryPath;
|
|
|
|
|
case ApplicationOriginalRowRole:
|
|
|
|
|
return index.row();
|
|
|
|
|
case ApplicationStartupNotifyRole:
|
|
|
|
|
return m_applicationList.at(index.row()).startupNotify;
|
|
|
|
|
case ApplicationLocationRole:
|
|
|
|
|
return m_applicationList.at(index.row()).location;
|
2014-10-28 12:27:54 +00:00
|
|
|
|
|
|
|
|
default:
|
2019-09-18 11:55:07 +00:00
|
|
|
return QVariant();
|
2014-10-28 12:27:54 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-21 12:14:33 +00:00
|
|
|
Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
2020-03-20 00:08:59 +00:00
|
|
|
return {};
|
2019-11-20 08:31:54 +00:00
|
|
|
return Qt::ItemIsDragEnabled|QAbstractListModel::flags(index);
|
2015-04-21 12:14:33 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
int ApplicationListModel::rowCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
if (parent.isValid()) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_applicationList.count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplicationListModel::moveRow(const QModelIndex& /* sourceParent */, int sourceRow, const QModelIndex& /* destinationParent */, int destinationChild)
|
|
|
|
|
{
|
|
|
|
|
moveItem(sourceRow, destinationChild);
|
|
|
|
|
}
|
2015-04-21 12:14:33 +00:00
|
|
|
|
2020-03-21 01:59:49 +00:00
|
|
|
void ApplicationListModel::setLocation(int row, LauncherLocation location)
|
2019-09-04 16:39:31 +00:00
|
|
|
{
|
2019-09-18 11:55:07 +00:00
|
|
|
if (row < 0 || row >= m_applicationList.length()) {
|
2019-09-04 16:39:31 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-20 00:08:59 +00:00
|
|
|
ApplicationData data = m_applicationList.at(row);
|
2019-09-18 11:55:07 +00:00
|
|
|
if (data.location == location) {
|
2019-09-04 16:39:31 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 01:59:49 +00:00
|
|
|
if (location == Favorites) {
|
2020-03-20 00:08:59 +00:00
|
|
|
qWarning() << "favoriting" << row << data.name;
|
2019-09-04 16:39:31 +00:00
|
|
|
// Deny favorites when full
|
|
|
|
|
if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
m_favorites.insert(row, data.storageId);
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
m_homeScreen->config().writeEntry("Favorites", m_favorites);
|
|
|
|
|
emit favoriteCountChanged();
|
|
|
|
|
|
|
|
|
|
// Out of favorites
|
2020-03-21 01:59:49 +00:00
|
|
|
} else if (data.location == Favorites) {
|
2019-09-18 11:55:07 +00:00
|
|
|
m_favorites.removeAll(data.storageId);
|
2019-09-04 16:39:31 +00:00
|
|
|
m_homeScreen->config().writeEntry("Favorites", m_favorites);
|
|
|
|
|
emit favoriteCountChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In Desktop
|
2020-03-21 01:59:49 +00:00
|
|
|
if (location == Desktop) {
|
2019-09-18 11:55:07 +00:00
|
|
|
m_desktopItems.insert(data.storageId);
|
2019-12-06 21:04:33 +00:00
|
|
|
m_homeScreen->config().writeEntry("DesktopItems", m_desktopItems.values());
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
// Out of Desktop
|
2020-03-21 01:59:49 +00:00
|
|
|
} else if (data.location == Desktop) {
|
2019-09-18 11:55:07 +00:00
|
|
|
m_desktopItems.remove(data.storageId);
|
2020-03-20 00:08:59 +00:00
|
|
|
m_homeScreen->config().writeEntry(QStringLiteral("DesktopItems"), m_desktopItems.values());
|
2019-09-04 16:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
data.location = location;
|
2019-09-04 16:39:31 +00:00
|
|
|
emit m_homeScreen->configNeedsSaving();
|
|
|
|
|
emit dataChanged(index(row, 0), index(row, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplicationListModel::moveItem(int row, int destination)
|
2015-03-05 12:37:39 +00:00
|
|
|
{
|
2019-09-18 11:55:07 +00:00
|
|
|
if (row < 0 || destination < 0 || row >= m_applicationList.length() ||
|
|
|
|
|
destination >= m_applicationList.length() || row == destination) {
|
2015-03-05 12:37:39 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (destination > row) {
|
|
|
|
|
++destination;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
beginMoveRows(QModelIndex(), row, row, QModelIndex(), destination);
|
|
|
|
|
if (destination > row) {
|
|
|
|
|
ApplicationData data = m_applicationList.at(row);
|
|
|
|
|
m_applicationList.insert(destination, data);
|
|
|
|
|
m_applicationList.takeAt(row);
|
2019-09-04 16:39:31 +00:00
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
} else {
|
|
|
|
|
ApplicationData data = m_applicationList.takeAt(row);
|
|
|
|
|
m_applicationList.insert(destination, data);
|
2015-04-10 22:23:49 +00:00
|
|
|
}
|
2015-03-18 13:34:05 +00:00
|
|
|
|
|
|
|
|
|
2019-09-18 11:55:07 +00:00
|
|
|
m_appOrder.clear();
|
|
|
|
|
m_appPositions.clear();
|
|
|
|
|
int i = 0;
|
2019-11-20 08:31:54 +00:00
|
|
|
for (const ApplicationData &app : qAsConst(m_applicationList)) {
|
2019-09-18 11:55:07 +00:00
|
|
|
m_appOrder << app.storageId;
|
|
|
|
|
m_appPositions[app.storageId] = i;
|
|
|
|
|
++i;
|
2015-03-18 13:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-04 16:39:31 +00:00
|
|
|
m_homeScreen->config().writeEntry("AppOrder", m_appOrder);
|
2019-09-18 11:55:07 +00:00
|
|
|
|
|
|
|
|
endMoveRows();
|
2015-03-05 12:37:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplicationListModel::runApplication(const QString &storageId)
|
|
|
|
|
{
|
2014-10-28 12:27:54 +00:00
|
|
|
if (storageId.isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KService::Ptr service = KService::serviceByStorageId(storageId);
|
2020-05-10 16:07:36 +00:00
|
|
|
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service);
|
|
|
|
|
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
|
|
|
|
|
job->start();
|
2015-06-18 23:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-04 16:39:31 +00:00
|
|
|
int ApplicationListModel::maxFavoriteCount() const
|
2015-03-18 13:34:05 +00:00
|
|
|
{
|
2019-09-04 16:39:31 +00:00
|
|
|
return m_maxFavoriteCount;
|
2015-03-18 13:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-04 16:39:31 +00:00
|
|
|
void ApplicationListModel::setMaxFavoriteCount(int count)
|
2015-03-18 13:34:05 +00:00
|
|
|
{
|
2019-09-04 16:39:31 +00:00
|
|
|
if (m_maxFavoriteCount == count) {
|
2015-03-18 13:34:05 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-04 16:39:31 +00:00
|
|
|
if (m_maxFavoriteCount > count) {
|
|
|
|
|
while (m_favorites.size() > count && m_favorites.count() > 0) {
|
|
|
|
|
m_favorites.pop_back();
|
|
|
|
|
}
|
|
|
|
|
emit favoriteCountChanged();
|
2019-09-18 11:55:07 +00:00
|
|
|
|
2019-09-04 16:39:31 +00:00
|
|
|
int i = 0;
|
|
|
|
|
for (auto &app : m_applicationList) {
|
2020-03-21 01:59:49 +00:00
|
|
|
if (i >= count && app.location == Favorites) {
|
|
|
|
|
app.location = Grid;
|
2019-09-04 16:39:31 +00:00
|
|
|
emit dataChanged(index(i, 0), index(i, 0));
|
|
|
|
|
}
|
|
|
|
|
++i;
|
2019-09-18 11:55:07 +00:00
|
|
|
}
|
2015-03-18 13:34:05 +00:00
|
|
|
}
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
m_maxFavoriteCount = count;
|
|
|
|
|
m_homeScreen->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount);
|
|
|
|
|
|
|
|
|
|
emit maxFavoriteCountChanged();
|
2015-03-18 13:34:05 +00:00
|
|
|
}
|
2019-09-04 16:39:31 +00:00
|
|
|
|
|
|
|
|
#include "moc_applicationlistmodel.cpp"
|
|
|
|
|
|