mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
Currently delegates do not get deleted when removed from models. Due to the complexity of drag state and other objects, we can't simply delete the delegate when removed from the model because they might still be involved in animations or other state at the time of removal. Use smart pointers to have the delegate objects deleted instead. QML unfortunately doesn't support QSharedPointer, so we need to expose raw pointers to it.
139 lines
3.7 KiB
C++
139 lines
3.7 KiB
C++
// SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "applicationlistmodel.h"
|
|
|
|
#include <QByteArray>
|
|
#include <QDebug>
|
|
#include <QModelIndex>
|
|
#include <QProcess>
|
|
#include <QQuickWindow>
|
|
|
|
#include <KApplicationTrader>
|
|
#include <KConfigGroup>
|
|
#include <KIO/ApplicationLauncherJob>
|
|
#include <KNotificationJobUiDelegate>
|
|
#include <KService>
|
|
#include <KSharedConfig>
|
|
#include <KSycoca>
|
|
|
|
#include <chrono>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
|
: QAbstractListModel(parent)
|
|
, m_reloadAppsTimer{new QTimer{this}}
|
|
{
|
|
m_reloadAppsTimer->setSingleShot(true);
|
|
m_reloadAppsTimer->setInterval(100ms);
|
|
connect(m_reloadAppsTimer, &QTimer::timeout, this, &ApplicationListModel::sycocaDbChanged);
|
|
|
|
connect(KSycoca::self(), &KSycoca::databaseChanged, m_reloadAppsTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
|
|
|
// initialize wayland window checking
|
|
KWayland::Client::ConnectionThread *connection = KWayland::Client::ConnectionThread::fromApplication(this);
|
|
if (!connection) {
|
|
return;
|
|
}
|
|
|
|
load();
|
|
}
|
|
|
|
ApplicationListModel::~ApplicationListModel() = default;
|
|
|
|
QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
|
{
|
|
return {{DelegateRole, QByteArrayLiteral("delegate")}};
|
|
}
|
|
|
|
void ApplicationListModel::sycocaDbChanged()
|
|
{
|
|
load();
|
|
}
|
|
|
|
void ApplicationListModel::load()
|
|
{
|
|
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
|
auto blgroup = KConfigGroup(cfg, QStringLiteral("Applications"));
|
|
|
|
const QStringList blacklist = blgroup.readEntry("blacklist", QStringList());
|
|
|
|
auto filter = [blacklist](const KService::Ptr &service) -> bool {
|
|
if (service->noDisplay()) {
|
|
return false;
|
|
}
|
|
|
|
if (!service->showOnCurrentPlatform()) {
|
|
return false;
|
|
}
|
|
|
|
if (blacklist.contains(service->desktopEntryName())) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
beginResetModel();
|
|
|
|
m_delegates.clear();
|
|
|
|
QList<FolioDelegate::Ptr> unorderedList;
|
|
|
|
const KService::List apps = KApplicationTrader::query(filter);
|
|
|
|
for (const KService::Ptr &service : apps) {
|
|
FolioApplication::Ptr app = std::make_shared<FolioApplication>(m_homeScreen, service);
|
|
FolioDelegate::Ptr delegate = std::make_shared<FolioDelegate>(app, m_homeScreen);
|
|
unorderedList << delegate;
|
|
}
|
|
|
|
std::sort(unorderedList.begin(), unorderedList.end(), [](FolioDelegate::Ptr &a1, FolioDelegate::Ptr &a2) {
|
|
return a1->application()->name().compare(a2->application()->name(), Qt::CaseInsensitive) < 0;
|
|
});
|
|
|
|
m_delegates << unorderedList;
|
|
|
|
endResetModel();
|
|
}
|
|
|
|
QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid()) {
|
|
return QVariant();
|
|
}
|
|
|
|
FolioDelegate::Ptr delegate = m_delegates.at(index.row());
|
|
|
|
switch (role) {
|
|
case Qt::DisplayRole:
|
|
case DelegateRole:
|
|
return QVariant::fromValue(delegate.get());
|
|
case NameRole:
|
|
if (!delegate->application()) {
|
|
return QVariant();
|
|
}
|
|
return m_delegates.at(index.row())->application()->name();
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
int ApplicationListModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid()) {
|
|
return 0;
|
|
}
|
|
|
|
return m_delegates.count();
|
|
}
|
|
|
|
ApplicationListSearchModel::ApplicationListSearchModel(HomeScreen *parent, ApplicationListModel *model)
|
|
: QSortFilterProxyModel(parent)
|
|
{
|
|
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
setSourceModel(model);
|
|
setFilterRole(ApplicationListModel::NameRole);
|
|
}
|