mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
homescreen: Start refactoring and cleaning
fix
This commit is contained in:
parent
25f36c4023
commit
b41e1f2b8a
22 changed files with 500 additions and 625 deletions
|
|
@ -17,8 +17,6 @@ set(mobileshellplugin_SRCS
|
|||
components/direction.cpp
|
||||
notifications/notificationthumbnailer.cpp
|
||||
notifications/notificationfilemenu.cpp
|
||||
homescreen/applicationlistmodel.cpp
|
||||
homescreen/favoritesmodel.cpp
|
||||
taskswitcher/displaysmodel.cpp
|
||||
)
|
||||
if (QT_MAJOR_VERSION STREQUAL "5")
|
||||
|
|
|
|||
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
// Self
|
||||
#include "favoritesmodel.h"
|
||||
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QModelIndex>
|
||||
|
||||
// KDE
|
||||
#include <KService>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <Plasma/Applet>
|
||||
#include <PlasmaQuick/AppletQuickItem>
|
||||
|
||||
constexpr int MAX_FAVOURITES = 5;
|
||||
|
||||
FavoritesModel::FavoritesModel(QObject *parent)
|
||||
: ApplicationListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
FavoritesModel::~FavoritesModel() = default;
|
||||
|
||||
QString FavoritesModel::storageToUniqueId(const QString &storageId) const
|
||||
{
|
||||
if (storageId.isEmpty()) {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
QString uniqueId = storageId + QStringLiteral("-") + QString::number(id);
|
||||
|
||||
while (m_appOrder.contains(uniqueId)) {
|
||||
uniqueId = storageId + QStringLiteral("-") + QString::number(++id);
|
||||
}
|
||||
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
QString FavoritesModel::uniqueToStorageId(const QString &uniqueId) const
|
||||
{
|
||||
if (uniqueId.isEmpty()) {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
return uniqueId.split(QLatin1Char('-')).first();
|
||||
}
|
||||
|
||||
void FavoritesModel::loadApplications()
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
m_applicationList.clear();
|
||||
|
||||
QSet<QString> appsToRemove;
|
||||
|
||||
for (const auto &uniqueId : m_appOrder) {
|
||||
const QString storageId = uniqueToStorageId(uniqueId);
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
ApplicationData data;
|
||||
data.name = service->name();
|
||||
data.icon = service->icon();
|
||||
data.storageId = service->storageId();
|
||||
data.uniqueId = uniqueId;
|
||||
data.entryPath = service->exec();
|
||||
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
||||
|
||||
if (m_favorites.contains(uniqueId)) {
|
||||
data.location = Favorites;
|
||||
} else if (m_desktopItems.contains(uniqueId)) {
|
||||
data.location = Desktop;
|
||||
}
|
||||
|
||||
m_applicationList << data;
|
||||
} else {
|
||||
appsToRemove.insert(uniqueId);
|
||||
}
|
||||
}
|
||||
|
||||
bool favChanged = false;
|
||||
|
||||
for (const auto &uniqueId : appsToRemove) {
|
||||
m_appOrder.removeAll(uniqueId);
|
||||
if (m_favorites.contains(uniqueId)) {
|
||||
favChanged = true;
|
||||
m_favorites.removeAll(uniqueId);
|
||||
}
|
||||
m_desktopItems.remove(uniqueId);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
emit m_applet->applet()->configNeedsSaving();
|
||||
}
|
||||
|
||||
if (favChanged) {
|
||||
emit favoriteCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void FavoritesModel::addFavorite(const QString &storageId, int row, LauncherLocation location)
|
||||
{
|
||||
if (row < 0 || row > m_applicationList.count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
const QString uniqueId = storageToUniqueId(service->storageId());
|
||||
ApplicationData data;
|
||||
data.name = service->name();
|
||||
data.icon = service->icon();
|
||||
data.storageId = service->storageId();
|
||||
data.uniqueId = uniqueId;
|
||||
data.entryPath = service->exec();
|
||||
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
||||
|
||||
bool favChanged = false;
|
||||
if (location == Favorites) {
|
||||
data.location = Favorites;
|
||||
m_favorites.insert(qMin(row, m_favorites.count()), uniqueId);
|
||||
favChanged = true;
|
||||
} else {
|
||||
data.location = location;
|
||||
m_desktopItems.insert(data.uniqueId);
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
m_applicationList.insert(row, data);
|
||||
m_appOrder.insert(row, uniqueId);
|
||||
endInsertRows();
|
||||
if (favChanged) {
|
||||
emit favoriteCountChanged();
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
emit m_applet->applet()->configNeedsSaving();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FavoritesModel::removeFavorite(int row)
|
||||
{
|
||||
if (row < 0 || row >= m_applicationList.count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
const QString uniqueId = m_applicationList[row].uniqueId;
|
||||
m_appOrder.removeAll(uniqueId);
|
||||
const bool favChanged = m_favorites.contains(uniqueId);
|
||||
m_favorites.removeAll(uniqueId);
|
||||
m_desktopItems.remove(uniqueId);
|
||||
m_appPositions.remove(uniqueId);
|
||||
m_applicationList.removeAt(row);
|
||||
endRemoveRows();
|
||||
|
||||
if (favChanged) {
|
||||
emit favoriteCountChanged();
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
emit m_applet->applet()->configNeedsSaving();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_favoritesmodel.cpp"
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Qt
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
|
||||
#include "applicationlistmodel.h"
|
||||
|
||||
class QString;
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class PlasmaWindowManagement;
|
||||
class PlasmaWindow;
|
||||
}
|
||||
}
|
||||
|
||||
class FavoritesModel;
|
||||
|
||||
class FavoritesModel : public ApplicationListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FavoritesModel(QObject *parent = nullptr);
|
||||
~FavoritesModel() override;
|
||||
|
||||
static FavoritesModel *instance()
|
||||
{
|
||||
static FavoritesModel *model = new FavoritesModel;
|
||||
return model;
|
||||
}
|
||||
|
||||
QString storageToUniqueId(const QString &storageId) const;
|
||||
QString uniqueToStorageId(const QString &uniqueId) const;
|
||||
|
||||
Q_INVOKABLE void addFavorite(const QString &storageId, int row, LauncherLocation location);
|
||||
Q_INVOKABLE void removeFavorite(int row);
|
||||
|
||||
Q_INVOKABLE void loadApplications() override;
|
||||
};
|
||||
|
|
@ -14,9 +14,6 @@
|
|||
#include "notifications/notificationfilemenu.h"
|
||||
#include "notifications/notificationthumbnailer.h"
|
||||
|
||||
#include "homescreen/applicationlistmodel.h"
|
||||
#include "homescreen/favoritesmodel.h"
|
||||
|
||||
#include "taskswitcher/displaysmodel.h"
|
||||
|
||||
#include "mobileshellsettings.h"
|
||||
|
|
@ -55,14 +52,6 @@ void MobileShellPlugin::registerTypes(const char *uri)
|
|||
// components
|
||||
qmlRegisterType<Direction>(uri, 1, 0, "Direction");
|
||||
|
||||
// homescreen
|
||||
qmlRegisterSingletonType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return ApplicationListModel::instance();
|
||||
});
|
||||
qmlRegisterSingletonType<FavoritesModel>(uri, 1, 0, "FavoritesModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return FavoritesModel::instance();
|
||||
});
|
||||
|
||||
// notifications
|
||||
qmlRegisterType<NotificationThumbnailer>(uri, 1, 0, "NotificationThumbnailer");
|
||||
qmlRegisterType<NotificationFileMenu>(uri, 1, 0, "NotificationFileMenu");
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ MouseArea { // use mousearea to ensure clicks don't go behind
|
|||
|
||||
MobileShell.HomeScreenControls.taskSwitcher.minimizeAll();
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
// close when an app opens
|
||||
property bool windowActive: Window.active
|
||||
|
|
|
|||
|
|
@ -213,12 +213,4 @@ Item {
|
|||
z: 999999
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
// listen to app launch errors
|
||||
Connections {
|
||||
target: MobileShell.ApplicationListModel
|
||||
function onLaunchError(msg) {
|
||||
MobileShell.HomeScreenControls.closeAppLaunchAnimation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
set(homescreen_SRCS
|
||||
homescreen.cpp
|
||||
desktopmodel.cpp
|
||||
applicationlistmodel.cpp
|
||||
)
|
||||
|
||||
add_library(plasma_containment_phone_homescreen MODULE ${homescreen_SRCS})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
// Self
|
||||
#include "applicationlistmodel.h"
|
||||
#include "../windowutil.h"
|
||||
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
|
||||
// KDE
|
||||
#include <KApplicationTrader>
|
||||
#include <KConfigGroup>
|
||||
#include <KIO/ApplicationLauncherJob>
|
||||
#include <KNotificationJobUiDelegate>
|
||||
#include <KService>
|
||||
|
|
@ -30,10 +30,6 @@
|
|||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
#include <Plasma/Applet>
|
||||
|
||||
constexpr int MAX_FAVOURITES = 5;
|
||||
|
||||
ApplicationListModel::ApplicationListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
|
|
@ -42,50 +38,49 @@ ApplicationListModel::ApplicationListModel(QObject *parent)
|
|||
#else
|
||||
connect(KSycoca::self(), &KSycoca::databaseChanged, this, &ApplicationListModel::sycocaDbChanged);
|
||||
#endif
|
||||
connect(WindowUtil::instance(), &WindowUtil::windowCreated, this, &ApplicationListModel::windowCreated);
|
||||
|
||||
loadSettings();
|
||||
// initialize wayland window checking
|
||||
KWayland::Client::ConnectionThread *connection = KWayland::Client::ConnectionThread::fromApplication(this);
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *registry = new KWayland::Client::Registry(this);
|
||||
registry->create(connection);
|
||||
|
||||
connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
||||
m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
|
||||
qRegisterMetaType<QVector<int>>("QVector<int>");
|
||||
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated, this, &ApplicationListModel::windowCreated);
|
||||
});
|
||||
|
||||
registry->setup();
|
||||
connection->roundtrip();
|
||||
}
|
||||
|
||||
ApplicationListModel::~ApplicationListModel() = default;
|
||||
|
||||
void ApplicationListModel::loadSettings()
|
||||
{
|
||||
if (!m_applet) {
|
||||
return;
|
||||
}
|
||||
m_favorites = m_applet->applet()->config().readEntry("Favorites", QStringList());
|
||||
const auto di = m_applet->applet()->config().readEntry("DesktopItems", QStringList());
|
||||
m_desktopItems = QSet<QString>(di.begin(), di.end());
|
||||
m_appOrder = m_applet->applet()->config().readEntry("AppOrder", QStringList());
|
||||
m_maxFavoriteCount = m_applet->applet()->config().readEntry("MaxFavoriteCount", MAX_FAVOURITES);
|
||||
|
||||
int i = 0;
|
||||
for (const QString &app : qAsConst(m_appOrder)) {
|
||||
m_appPositions[app] = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
// loadApplications();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||
{
|
||||
return {{ApplicationNameRole, QByteArrayLiteral("applicationName")},
|
||||
{ApplicationIconRole, QByteArrayLiteral("applicationIcon")},
|
||||
{ApplicationStorageIdRole, QByteArrayLiteral("applicationStorageId")},
|
||||
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
|
||||
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
|
||||
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
|
||||
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")},
|
||||
{ApplicationRunningRole, QByteArrayLiteral("applicationRunning")},
|
||||
{ApplicationUniqueIdRole, QByteArrayLiteral("applicationUniqueId")}};
|
||||
{ApplicationUniqueIdRole, QByteArrayLiteral("applicationUniqueId")},
|
||||
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")}};
|
||||
}
|
||||
|
||||
ApplicationListModel *ApplicationListModel::instance()
|
||||
{
|
||||
static ApplicationListModel *model = new ApplicationListModel;
|
||||
return model;
|
||||
}
|
||||
|
||||
void ApplicationListModel::sycocaDbChanged()
|
||||
{
|
||||
m_applicationList.clear();
|
||||
|
||||
loadApplications();
|
||||
}
|
||||
|
||||
|
|
@ -116,11 +111,6 @@ void ApplicationListModel::windowCreated(KWayland::Client::PlasmaWindow *window)
|
|||
}
|
||||
}
|
||||
|
||||
bool appNameLessThan(const ApplicationListModel::ApplicationData &a1, const ApplicationListModel::ApplicationData &a2)
|
||||
{
|
||||
return a1.name.compare(a2.name, Qt::CaseInsensitive) < 0;
|
||||
}
|
||||
|
||||
void ApplicationListModel::loadApplications()
|
||||
{
|
||||
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
||||
|
|
@ -132,9 +122,7 @@ void ApplicationListModel::loadApplications()
|
|||
|
||||
m_applicationList.clear();
|
||||
|
||||
QMap<int, ApplicationData> orderedList;
|
||||
QList<ApplicationData> unorderedList;
|
||||
QSet<QString> foundFavorites;
|
||||
|
||||
auto filter = [blacklist](const KService::Ptr &service) -> bool {
|
||||
if (service->noDisplay()) {
|
||||
|
|
@ -162,45 +150,16 @@ void ApplicationListModel::loadApplications()
|
|||
data.uniqueId = service->storageId();
|
||||
data.entryPath = service->exec();
|
||||
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
||||
|
||||
if (m_favorites.contains(data.uniqueId)) {
|
||||
data.location = Favorites;
|
||||
foundFavorites.insert(data.uniqueId);
|
||||
} else if (m_desktopItems.contains(data.uniqueId)) {
|
||||
data.location = Desktop;
|
||||
}
|
||||
|
||||
auto it = m_appPositions.constFind(data.uniqueId);
|
||||
if (it != m_appPositions.constEnd()) {
|
||||
orderedList[*it] = data;
|
||||
} else {
|
||||
unorderedList << data;
|
||||
}
|
||||
unorderedList << data;
|
||||
}
|
||||
|
||||
blgroup.writeEntry("blacklist", blacklist);
|
||||
cfg->sync();
|
||||
std::sort(unorderedList.begin(), unorderedList.end(), [](const ApplicationListModel::ApplicationData &a1, const ApplicationListModel::ApplicationData &a2) {
|
||||
return a1.name.compare(a2.name, Qt::CaseInsensitive) < 0;
|
||||
});
|
||||
|
||||
std::sort(unorderedList.begin(), unorderedList.end(), appNameLessThan);
|
||||
m_applicationList << orderedList.values();
|
||||
m_applicationList << unorderedList;
|
||||
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
|
||||
bool favChanged = false;
|
||||
for (const auto &item : m_favorites) {
|
||||
if (!foundFavorites.contains(item)) {
|
||||
favChanged = true;
|
||||
m_favorites.removeAll(item);
|
||||
}
|
||||
}
|
||||
if (favChanged) {
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
}
|
||||
emit favoriteCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
||||
|
|
@ -219,29 +178,19 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
|||
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;
|
||||
case ApplicationRunningRole:
|
||||
return m_applicationList.at(index.row()).window != nullptr;
|
||||
case ApplicationUniqueIdRole:
|
||||
return m_applicationList.at(index.row()).uniqueId;
|
||||
|
||||
case ApplicationLocationRole:
|
||||
return m_applicationList.at(index.row()).location;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags ApplicationListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
return Qt::ItemIsDragEnabled | QAbstractListModel::flags(index);
|
||||
}
|
||||
|
||||
int ApplicationListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
|
|
@ -251,103 +200,6 @@ int ApplicationListModel::rowCount(const QModelIndex &parent) const
|
|||
return m_applicationList.count();
|
||||
}
|
||||
|
||||
void ApplicationListModel::moveRow(const QModelIndex & /* sourceParent */, int sourceRow, const QModelIndex & /* destinationParent */, int destinationChild)
|
||||
{
|
||||
moveItem(sourceRow, destinationChild);
|
||||
}
|
||||
|
||||
void ApplicationListModel::setLocation(int row, LauncherLocation location)
|
||||
{
|
||||
if (row < 0 || row >= m_applicationList.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationData data = m_applicationList.at(row);
|
||||
if (data.location == location) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (location == Favorites) {
|
||||
qWarning() << "favoriting" << row << data.name;
|
||||
// Deny favorites when full
|
||||
if (row >= m_maxFavoriteCount || m_favorites.count() >= m_maxFavoriteCount || m_favorites.contains(data.uniqueId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_favorites.insert(row, data.uniqueId);
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
}
|
||||
emit favoriteCountChanged();
|
||||
|
||||
// Out of favorites
|
||||
} else if (data.location == Favorites) {
|
||||
m_favorites.removeAll(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("Favorites", m_favorites);
|
||||
}
|
||||
emit favoriteCountChanged();
|
||||
}
|
||||
|
||||
// In Desktop
|
||||
if (location == Desktop) {
|
||||
m_desktopItems.insert(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
}
|
||||
|
||||
// Out of Desktop
|
||||
} else if (data.location == Desktop) {
|
||||
m_desktopItems.remove(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry(QStringLiteral("DesktopItems"), m_desktopItems.values());
|
||||
}
|
||||
}
|
||||
|
||||
data.location = location;
|
||||
if (m_applet) {
|
||||
emit m_applet->applet()->configNeedsSaving();
|
||||
}
|
||||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
}
|
||||
|
||||
void ApplicationListModel::moveItem(int row, int destination)
|
||||
{
|
||||
if (row < 0 || destination < 0 || row >= m_applicationList.length() || destination >= m_applicationList.length() || row == destination) {
|
||||
return;
|
||||
}
|
||||
if (destination > row) {
|
||||
++destination;
|
||||
}
|
||||
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), destination);
|
||||
if (destination > row) {
|
||||
ApplicationData data = m_applicationList.at(row);
|
||||
m_applicationList.insert(destination, data);
|
||||
m_applicationList.takeAt(row);
|
||||
|
||||
} else {
|
||||
ApplicationData data = m_applicationList.takeAt(row);
|
||||
m_applicationList.insert(destination, data);
|
||||
}
|
||||
|
||||
m_appOrder.clear();
|
||||
m_appPositions.clear();
|
||||
int i = 0;
|
||||
for (const ApplicationData &app : qAsConst(m_applicationList)) {
|
||||
m_appOrder << app.uniqueId;
|
||||
m_appPositions[app.uniqueId] = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("AppOrder", m_appOrder);
|
||||
}
|
||||
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void ApplicationListModel::runApplication(const QString &storageId)
|
||||
{
|
||||
if (storageId.isEmpty()) {
|
||||
|
|
@ -373,56 +225,6 @@ void ApplicationListModel::runApplication(const QString &storageId)
|
|||
});
|
||||
}
|
||||
|
||||
int ApplicationListModel::maxFavoriteCount() const
|
||||
{
|
||||
return m_maxFavoriteCount;
|
||||
}
|
||||
|
||||
void ApplicationListModel::setMaxFavoriteCount(int count)
|
||||
{
|
||||
if (m_maxFavoriteCount == count) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_maxFavoriteCount > count) {
|
||||
while (m_favorites.size() > count && m_favorites.count() > 0) {
|
||||
m_favorites.pop_back();
|
||||
}
|
||||
emit favoriteCountChanged();
|
||||
|
||||
int i = 0;
|
||||
for (auto &app : m_applicationList) {
|
||||
if (i >= count && app.location == Favorites) {
|
||||
app.location = Grid;
|
||||
emit dataChanged(index(i, 0), index(i, 0));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
m_maxFavoriteCount = count;
|
||||
if (m_applet) {
|
||||
m_applet->applet()->config().writeEntry("MaxFavoriteCount", m_maxFavoriteCount);
|
||||
}
|
||||
|
||||
emit maxFavoriteCountChanged();
|
||||
}
|
||||
|
||||
PlasmaQuick::AppletQuickItem *ApplicationListModel::applet() const
|
||||
{
|
||||
return m_applet;
|
||||
}
|
||||
|
||||
void ApplicationListModel::setApplet(PlasmaQuick::AppletQuickItem *applet)
|
||||
{
|
||||
if (m_applet == applet) {
|
||||
return;
|
||||
}
|
||||
m_applet = applet;
|
||||
loadSettings();
|
||||
emit appletChanged();
|
||||
}
|
||||
|
||||
void ApplicationListModel::setMinimizedDelegate(int row, QQuickItem *delegate)
|
||||
{
|
||||
if (row < 0 || row >= m_applicationList.count()) {
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
#pragma once
|
||||
|
||||
// Qt
|
||||
#include <PlasmaQuick/AppletQuickItem>
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
|
@ -26,20 +25,18 @@ class PlasmaWindow;
|
|||
}
|
||||
}
|
||||
|
||||
class ApplicationListModel;
|
||||
|
||||
/**
|
||||
* @short The base application list, used directly by the app drawer.
|
||||
*
|
||||
* Items that are displayed on the desktop/pinned are done by DesktopModel, which is a subclass.
|
||||
*/
|
||||
class ApplicationListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(PlasmaQuick::AppletQuickItem *applet READ applet WRITE setApplet NOTIFY appletChanged)
|
||||
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
Q_PROPERTY(int favoriteCount READ favoriteCount NOTIFY favoriteCountChanged)
|
||||
Q_PROPERTY(int maxFavoriteCount READ maxFavoriteCount WRITE setMaxFavoriteCount NOTIFY maxFavoriteCountChanged)
|
||||
|
||||
public:
|
||||
enum LauncherLocation { Grid = 0, Favorites, Desktop };
|
||||
// this enum is solely used by DesktopModel
|
||||
enum LauncherLocation { None = 0, Favorites, Desktop };
|
||||
Q_ENUM(LauncherLocation)
|
||||
|
||||
struct ApplicationData {
|
||||
|
|
@ -48,9 +45,9 @@ public:
|
|||
QString icon;
|
||||
QString storageId;
|
||||
QString entryPath;
|
||||
LauncherLocation location = LauncherLocation::Grid;
|
||||
bool startupNotify = true;
|
||||
KWayland::Client::PlasmaWindow *window = nullptr;
|
||||
LauncherLocation location = LauncherLocation::None; // only for DesktopModel
|
||||
};
|
||||
|
||||
enum Roles {
|
||||
|
|
@ -58,56 +55,23 @@ public:
|
|||
ApplicationIconRole,
|
||||
ApplicationStorageIdRole,
|
||||
ApplicationEntryPathRole,
|
||||
ApplicationOriginalRowRole,
|
||||
ApplicationStartupNotifyRole,
|
||||
ApplicationLocationRole,
|
||||
ApplicationRunningRole,
|
||||
ApplicationUniqueIdRole
|
||||
ApplicationUniqueIdRole,
|
||||
ApplicationLocationRole // only valid for DesktopModel
|
||||
};
|
||||
|
||||
ApplicationListModel(QObject *parent = nullptr);
|
||||
~ApplicationListModel() override;
|
||||
|
||||
static ApplicationListModel *instance()
|
||||
{
|
||||
static ApplicationListModel *model = new ApplicationListModel;
|
||||
return model;
|
||||
}
|
||||
|
||||
void loadSettings();
|
||||
static ApplicationListModel *instance();
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
|
||||
void moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
|
||||
|
||||
int count() const
|
||||
{
|
||||
return m_applicationList.count();
|
||||
}
|
||||
int favoriteCount() const
|
||||
{
|
||||
return m_favorites.count();
|
||||
}
|
||||
|
||||
int maxFavoriteCount() const;
|
||||
void setMaxFavoriteCount(int count);
|
||||
|
||||
void setApplet(PlasmaQuick::AppletQuickItem *applet);
|
||||
PlasmaQuick::AppletQuickItem *applet() const;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
|
||||
|
||||
Q_INVOKABLE void setLocation(int row, LauncherLocation location);
|
||||
|
||||
Q_INVOKABLE void moveItem(int row, int destination);
|
||||
|
||||
Q_INVOKABLE void runApplication(const QString &storageId);
|
||||
|
||||
Q_INVOKABLE virtual void loadApplications();
|
||||
Q_INVOKABLE void runApplication(const QString &storageId);
|
||||
|
||||
Q_INVOKABLE void setMinimizedDelegate(int row, QQuickItem *delegate);
|
||||
Q_INVOKABLE void unsetMinimizedDelegate(int row, QQuickItem *delegate);
|
||||
|
|
@ -117,19 +81,10 @@ public Q_SLOTS:
|
|||
void windowCreated(KWayland::Client::PlasmaWindow *window);
|
||||
|
||||
Q_SIGNALS:
|
||||
void countChanged();
|
||||
void favoriteCountChanged();
|
||||
void maxFavoriteCountChanged();
|
||||
void appletChanged();
|
||||
void launchError(const QString &msg);
|
||||
|
||||
protected:
|
||||
QList<ApplicationData> m_applicationList;
|
||||
|
||||
PlasmaQuick::AppletQuickItem *m_applet = nullptr;
|
||||
int m_maxFavoriteCount = 0;
|
||||
QStringList m_appOrder;
|
||||
QStringList m_favorites;
|
||||
QSet<QString> m_desktopItems;
|
||||
QHash<QString, int> m_appPositions;
|
||||
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
|
||||
};
|
||||
310
containments/homescreens/default/desktopmodel.cpp
Normal file
310
containments/homescreens/default/desktopmodel.cpp
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
// 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
|
||||
|
||||
// Self
|
||||
#include "desktopmodel.h"
|
||||
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QModelIndex>
|
||||
|
||||
// KDE
|
||||
#include <KService>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <Plasma/Applet>
|
||||
#include <PlasmaQuick/AppletQuickItem>
|
||||
|
||||
const int MAX_FAVORITES = 5;
|
||||
|
||||
DesktopModel::DesktopModel(QObject *parent, Plasma::Applet *applet)
|
||||
: ApplicationListModel(parent)
|
||||
, m_applet{applet}
|
||||
{
|
||||
}
|
||||
|
||||
DesktopModel::~DesktopModel() = default;
|
||||
|
||||
QString DesktopModel::storageToUniqueId(const QString &storageId) const
|
||||
{
|
||||
if (storageId.isEmpty()) {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
QString uniqueId = storageId + QStringLiteral("-") + QString::number(id);
|
||||
|
||||
while (m_appOrder.contains(uniqueId)) {
|
||||
uniqueId = storageId + QStringLiteral("-") + QString::number(++id);
|
||||
}
|
||||
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
QString DesktopModel::uniqueToStorageId(const QString &uniqueId) const
|
||||
{
|
||||
if (uniqueId.isEmpty()) {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
return uniqueId.split(QLatin1Char('-')).first();
|
||||
}
|
||||
|
||||
void DesktopModel::loadSettings()
|
||||
{
|
||||
if (!m_applet) {
|
||||
return;
|
||||
}
|
||||
m_favorites = m_applet->config().readEntry("Favorites", QStringList());
|
||||
const auto di = m_applet->config().readEntry("DesktopItems", QStringList());
|
||||
m_desktopItems = QSet<QString>(di.begin(), di.end());
|
||||
m_appOrder = m_applet->config().readEntry("AppOrder", QStringList());
|
||||
|
||||
int i = 0;
|
||||
for (const QString &app : qAsConst(m_appOrder)) {
|
||||
m_appPositions[app] = i;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopModel::load()
|
||||
{
|
||||
loadSettings();
|
||||
|
||||
// load applications
|
||||
beginResetModel();
|
||||
|
||||
m_applicationList.clear();
|
||||
|
||||
QSet<QString> appsToRemove;
|
||||
|
||||
for (const auto &uniqueId : m_appOrder) {
|
||||
const QString storageId = uniqueToStorageId(uniqueId);
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
ApplicationData data;
|
||||
data.name = service->name();
|
||||
data.icon = service->icon();
|
||||
data.storageId = service->storageId();
|
||||
data.uniqueId = uniqueId;
|
||||
data.entryPath = service->exec();
|
||||
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
||||
|
||||
if (m_favorites.contains(uniqueId)) {
|
||||
data.location = Favorites;
|
||||
} else if (m_desktopItems.contains(uniqueId)) {
|
||||
data.location = Desktop;
|
||||
}
|
||||
|
||||
m_applicationList << data;
|
||||
} else {
|
||||
appsToRemove.insert(uniqueId);
|
||||
}
|
||||
}
|
||||
|
||||
bool favChanged = false;
|
||||
|
||||
for (const auto &uniqueId : appsToRemove) {
|
||||
m_appOrder.removeAll(uniqueId);
|
||||
if (m_favorites.contains(uniqueId)) {
|
||||
favChanged = true;
|
||||
m_favorites.removeAll(uniqueId);
|
||||
}
|
||||
m_desktopItems.remove(uniqueId);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
|
||||
Q_EMIT countChanged();
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
Q_EMIT m_applet->configNeedsSaving();
|
||||
}
|
||||
|
||||
if (favChanged) {
|
||||
Q_EMIT favoriteCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int DesktopModel::count()
|
||||
{
|
||||
return m_applicationList.count();
|
||||
}
|
||||
|
||||
int DesktopModel::favoriteCount()
|
||||
{
|
||||
return m_favorites.count();
|
||||
}
|
||||
|
||||
int DesktopModel::maxFavoriteCount()
|
||||
{
|
||||
return MAX_FAVORITES;
|
||||
}
|
||||
|
||||
void DesktopModel::setLocation(int row, LauncherLocation location)
|
||||
{
|
||||
if (row < 0 || row >= m_applicationList.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationData data = m_applicationList.at(row);
|
||||
if (data.location == location) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (location == Favorites) {
|
||||
qWarning() << "favoriting" << row << data.name;
|
||||
// Deny favorites when full
|
||||
if (row >= maxFavoriteCount() || m_favorites.count() >= maxFavoriteCount() || m_favorites.contains(data.uniqueId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_favorites.insert(row, data.uniqueId);
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("Favorites", m_favorites);
|
||||
}
|
||||
Q_EMIT favoriteCountChanged();
|
||||
|
||||
// Out of favorites
|
||||
} else if (data.location == Favorites) {
|
||||
m_favorites.removeAll(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("Favorites", m_favorites);
|
||||
}
|
||||
Q_EMIT favoriteCountChanged();
|
||||
}
|
||||
|
||||
// In Desktop
|
||||
if (location == Desktop) {
|
||||
m_desktopItems.insert(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
}
|
||||
|
||||
// Out of Desktop
|
||||
} else if (data.location == Desktop) {
|
||||
m_desktopItems.remove(data.uniqueId);
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry(QStringLiteral("DesktopItems"), m_desktopItems.values());
|
||||
}
|
||||
}
|
||||
|
||||
data.location = location;
|
||||
if (m_applet) {
|
||||
Q_EMIT m_applet->configNeedsSaving();
|
||||
}
|
||||
Q_EMIT dataChanged(index(row, 0), index(row, 0));
|
||||
}
|
||||
|
||||
void DesktopModel::moveItem(int row, int destination)
|
||||
{
|
||||
if (row < 0 || destination < 0 || row >= m_applicationList.length() || destination >= m_applicationList.length() || row == destination) {
|
||||
return;
|
||||
}
|
||||
if (destination > row) {
|
||||
++destination;
|
||||
}
|
||||
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), destination);
|
||||
if (destination > row) {
|
||||
ApplicationData data = m_applicationList.at(row);
|
||||
m_applicationList.insert(destination, data);
|
||||
m_applicationList.takeAt(row);
|
||||
|
||||
} else {
|
||||
ApplicationData data = m_applicationList.takeAt(row);
|
||||
m_applicationList.insert(destination, data);
|
||||
}
|
||||
|
||||
m_appOrder.clear();
|
||||
m_appPositions.clear();
|
||||
int i = 0;
|
||||
for (const ApplicationData &app : qAsConst(m_applicationList)) {
|
||||
m_appOrder << app.uniqueId;
|
||||
m_appPositions[app.uniqueId] = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("AppOrder", m_appOrder);
|
||||
}
|
||||
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void DesktopModel::addFavorite(const QString &storageId, int row, LauncherLocation location)
|
||||
{
|
||||
if (row < 0 || row > m_applicationList.count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
const QString uniqueId = storageToUniqueId(service->storageId());
|
||||
ApplicationData data;
|
||||
data.name = service->name();
|
||||
data.icon = service->icon();
|
||||
data.storageId = service->storageId();
|
||||
data.uniqueId = uniqueId;
|
||||
data.entryPath = service->exec();
|
||||
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool();
|
||||
|
||||
bool favChanged = false;
|
||||
if (location == Favorites) {
|
||||
data.location = Favorites;
|
||||
m_favorites.insert(qMin(row, m_favorites.count()), uniqueId);
|
||||
favChanged = true;
|
||||
} else {
|
||||
data.location = location;
|
||||
m_desktopItems.insert(data.uniqueId);
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
m_applicationList.insert(row, data);
|
||||
m_appOrder.insert(row, uniqueId);
|
||||
endInsertRows();
|
||||
if (favChanged) {
|
||||
Q_EMIT favoriteCountChanged();
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
Q_EMIT m_applet->configNeedsSaving();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopModel::removeFavorite(int row)
|
||||
{
|
||||
if (row < 0 || row >= m_applicationList.count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
const QString uniqueId = m_applicationList[row].uniqueId;
|
||||
m_appOrder.removeAll(uniqueId);
|
||||
|
||||
const bool favChanged = m_favorites.contains(uniqueId);
|
||||
m_favorites.removeAll(uniqueId);
|
||||
m_desktopItems.remove(uniqueId);
|
||||
m_appPositions.remove(uniqueId);
|
||||
m_applicationList.removeAt(row);
|
||||
endRemoveRows();
|
||||
|
||||
if (favChanged) {
|
||||
Q_EMIT favoriteCountChanged();
|
||||
}
|
||||
|
||||
if (m_applet) {
|
||||
m_applet->config().writeEntry("Favorites", m_favorites);
|
||||
m_applet->config().writeEntry("AppOrder", m_appOrder);
|
||||
m_applet->config().writeEntry("DesktopItems", m_desktopItems.values());
|
||||
Q_EMIT m_applet->configNeedsSaving();
|
||||
}
|
||||
}
|
||||
59
containments/homescreens/default/desktopmodel.h
Normal file
59
containments/homescreens/default/desktopmodel.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// SPDX-FileCopyrightText: 2021 Marco Martin <mart@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
// Qt
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
|
||||
// KDE
|
||||
#include <Plasma/Applet>
|
||||
|
||||
#include "applicationlistmodel.h"
|
||||
|
||||
/**
|
||||
* @short Filtered application list for applications on the desktop and pinned bar.
|
||||
*/
|
||||
class DesktopModel : public ApplicationListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
Q_PROPERTY(int favoriteCount READ favoriteCount NOTIFY favoriteCountChanged)
|
||||
Q_PROPERTY(int maxFavoriteCount READ maxFavoriteCount CONSTANT)
|
||||
|
||||
public:
|
||||
DesktopModel(QObject *parent = nullptr, Plasma::Applet *applet = nullptr);
|
||||
~DesktopModel() override;
|
||||
|
||||
QString storageToUniqueId(const QString &storageId) const;
|
||||
QString uniqueToStorageId(const QString &uniqueId) const;
|
||||
|
||||
void loadSettings();
|
||||
Q_INVOKABLE void load();
|
||||
|
||||
int count();
|
||||
int favoriteCount();
|
||||
int maxFavoriteCount();
|
||||
|
||||
Q_INVOKABLE void setLocation(int row, LauncherLocation location);
|
||||
Q_INVOKABLE void moveItem(int row, int destination);
|
||||
|
||||
Q_INVOKABLE void addFavorite(const QString &storageId, int row, LauncherLocation location);
|
||||
Q_INVOKABLE void removeFavorite(int row);
|
||||
|
||||
Q_SIGNALS:
|
||||
void countChanged();
|
||||
void favoriteCountChanged();
|
||||
|
||||
private:
|
||||
QStringList m_appOrder;
|
||||
QStringList m_favorites;
|
||||
QSet<QString> m_desktopItems;
|
||||
QHash<QString, int> m_appPositions;
|
||||
|
||||
Plasma::Applet *m_applet = nullptr;
|
||||
};
|
||||
|
|
@ -1,19 +1,33 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "homescreen.h"
|
||||
|
||||
#include <KWindowSystem>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QQuickItem>
|
||||
#include <QtQml>
|
||||
|
||||
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
||||
: Plasma::Containment(parent, data, args)
|
||||
: Plasma::Containment{parent, data, args}
|
||||
{
|
||||
setHasConfigurationInterface(true);
|
||||
|
||||
ApplicationListModel *applicationListModel = new ApplicationListModel{this};
|
||||
DesktopModel *desktopModel = new DesktopModel{this, this};
|
||||
qmlRegisterSingletonType<ApplicationListModel>("org.kde.phone.homescreen.default",
|
||||
1,
|
||||
0,
|
||||
"ApplicationListModel",
|
||||
[applicationListModel](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return applicationListModel;
|
||||
});
|
||||
qmlRegisterSingletonType<DesktopModel>("org.kde.phone.homescreen.default", 1, 0, "DesktopModel", [desktopModel](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return desktopModel;
|
||||
});
|
||||
|
||||
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plasma/Containment>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <applicationlistmodel.h>
|
||||
#include <desktopmodel.h>
|
||||
|
||||
class HomeScreen : public Plasma::Containment
|
||||
{
|
||||
|
|
@ -24,7 +26,4 @@ public:
|
|||
|
||||
Q_SIGNALS:
|
||||
void showingDesktopChanged(bool showingDesktop);
|
||||
|
||||
private:
|
||||
bool m_showAllApps = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import org.kde.kquickcontrolsaddons 2.0
|
|||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
import "private" as Private
|
||||
|
||||
|
|
@ -50,9 +51,9 @@ ContainmentLayoutManager.ItemContainer {
|
|||
}
|
||||
|
||||
if (!MobileShell.HomeScreenControls.taskSwitcherVisible) {
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
|
||||
} else {
|
||||
MobileShell.ApplicationListModel.unsetMinimizedDelegate(index, delegate);
|
||||
HomeScreenLib.DesktopModel.unsetMinimizedDelegate(index, delegate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -63,8 +64,8 @@ ContainmentLayoutManager.ItemContainer {
|
|||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, modelData.applicationName);
|
||||
}
|
||||
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
MobileShell.ApplicationListModel.runApplication(modelData.applicationStorageId);
|
||||
HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
|
||||
HomeScreenLib.DesktopModel.runApplication(modelData.applicationStorageId);
|
||||
}
|
||||
|
||||
readonly property bool applicationRunning: model.applicationRunning
|
||||
|
|
@ -231,7 +232,7 @@ ContainmentLayoutManager.ItemContainer {
|
|||
color: Qt.rgba(0, 0, 0, 0.3)
|
||||
}
|
||||
}
|
||||
Item {Layout.fillHeight:true}
|
||||
Item { Layout.fillHeight: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import "appdrawer"
|
|||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
|
@ -103,7 +104,7 @@ Item {
|
|||
|
||||
appletsLayout: contents.appletsLayout
|
||||
visible: favoriteStrip.flow.children.length > 0 || contents.launcherDragManager.active || contents.containsDrag
|
||||
opacity: contents.launcherDragManager.active && MobileShell.ApplicationListModel.favoriteCount >= MobileShell.ApplicationListModel.maxFavoriteCount ? 0.3 : 1
|
||||
opacity: contents.launcherDragManager.active && HomeScreenLib.DesktopModel.favoriteCount >= HomeScreenLib.DesktopModel.maxFavoriteCount ? 0.3 : 1
|
||||
|
||||
TapHandler {
|
||||
target: favoriteStrip
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.kde.draganddrop 2.0 as DragDrop
|
|||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
import "private" as Private
|
||||
|
||||
|
|
@ -51,6 +52,9 @@ DragDrop.DropArea {
|
|||
}
|
||||
|
||||
property bool inAppletEditMode: false
|
||||
|
||||
property var applicationListModel: HomeScreenLib.ApplicationListModel
|
||||
property var desktopModel: HomeScreenLib.DesktopModel
|
||||
|
||||
Connections {
|
||||
target: plasmoid
|
||||
|
|
@ -67,7 +71,7 @@ DragDrop.DropArea {
|
|||
onDragMove: {
|
||||
let posInFavorites = favoriteStrip.mapFromItem(this, event.x, event.y);
|
||||
if (posInFavorites.y > 0) {
|
||||
if (MobileShell.ApplicationListModel.favoriteCount >= MobileShell.ApplicationListModel.maxFavoriteCount ) {
|
||||
if (desktopModel.favoriteCount >= desktopModel.maxFavoriteCount) {
|
||||
launcherDragManager.hideSpacer();
|
||||
} else {
|
||||
launcherDragManager.showSpacerAtPos(event.x, event.y, favoriteStrip);
|
||||
|
|
@ -110,12 +114,12 @@ DragDrop.DropArea {
|
|||
|
||||
let posInFavorites = favoriteStrip.flow.mapFromItem(this, event.x, event.y);
|
||||
if (posInFavorites.y > 0) {
|
||||
if (MobileShell.ApplicationListModel.favoriteCount >= MobileShell.ApplicationListModel.maxFavoriteCount ) {
|
||||
if (desktopModel.favoriteCount >= desktopModel.maxFavoriteCount ) {
|
||||
return;
|
||||
}
|
||||
|
||||
let pos = Math.min(MobileShell.FavoritesModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
|
||||
MobileShell.FavoritesModel.addFavorite(storageId, pos, MobileShell.ApplicationListModel.Favorites)
|
||||
let pos = Math.min(desktopModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
|
||||
desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Favorites)
|
||||
let item = launcherRepeater.itemAt(pos);
|
||||
|
||||
if (item) {
|
||||
|
|
@ -129,8 +133,8 @@ DragDrop.DropArea {
|
|||
return;
|
||||
}
|
||||
|
||||
let pos = MobileShell.FavoritesModel.count;
|
||||
MobileShell.FavoritesModel.addFavorite(storageId, pos, MobileShell.ApplicationListModel.Desktop)
|
||||
let pos = desktopModel.count;
|
||||
desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Desktop)
|
||||
let item = launcherRepeater.itemAt(pos);
|
||||
|
||||
event.accept(event.proposedAction);
|
||||
|
|
@ -230,4 +234,3 @@ DragDrop.DropArea {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
import QtQuick 2.4
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
|
@ -16,7 +18,8 @@ Item {
|
|||
property FavoriteStrip favoriteStrip
|
||||
property ContainmentLayoutManager.ItemContainer currentlyDraggedDelegate
|
||||
property bool active
|
||||
property QtObject model: MobileShell.ApplicationListModel
|
||||
|
||||
property var desktopModel: HomeScreenLib.DesktopModel
|
||||
|
||||
readonly property Item spacer: Item {
|
||||
width: favoriteStrip.cellWidth
|
||||
|
|
@ -41,15 +44,12 @@ Item {
|
|||
var pos = favoriteStrip.flow.mapFromItem(delegate, 0, 0);
|
||||
newRow = Math.floor((pos.x + dragCenterX) / delegate.width);
|
||||
|
||||
//root.model.setLocation(delegate.modelData.index, MobileShell.ApplicationListModel.Favorites);
|
||||
|
||||
showSpacer(delegate, dragCenterX, dragCenterY);
|
||||
root.model.moveItem(delegate.modelData.index, newRow);
|
||||
HomeScreenLib.DesktopModel.moveItem(delegate.modelData.index, newRow);
|
||||
|
||||
// Put it on desktop
|
||||
} else {
|
||||
var pos = appletsLayout.mapFromItem(delegate, 0, 0);
|
||||
//root.model.setLocation(delegate.modelData.index, MobileShell.ApplicationListModel.Desktop);
|
||||
|
||||
showSpacer(delegate, dragCenterX, dragCenterY);
|
||||
return;
|
||||
|
|
@ -162,8 +162,8 @@ Item {
|
|||
if (!item.modelData) {
|
||||
return appletsLayout;
|
||||
} else if (favoriteStrip.contains(Qt.point(0,favoriteStrip.frame.mapFromItem(item, dragCenterX, dragCenterY).y))
|
||||
&& (item.modelData.applicationLocation == MobileShell.ApplicationListModel.Favorites
|
||||
|| root.model.favoriteCount < root.model.maxFavoriteCount)) {
|
||||
&& (item.modelData.applicationLocation == HomeScreenLib.DesktopModel.Favorites
|
||||
|| HomeScreenLib.DesktopModel.favoriteCount < HomeScreenLib.DesktopModel.maxFavoriteCount)) {
|
||||
return favoriteStrip;
|
||||
} else {
|
||||
return appletsLayout;
|
||||
|
|
@ -257,14 +257,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
if (!child) {
|
||||
/* if (item.y < container.flow.height/2) {
|
||||
child = container.flow.children[0];
|
||||
} else {
|
||||
child = container.flow.children[container.flow.children.length - 1];
|
||||
}*/
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
|
@ -277,7 +269,7 @@ Item {
|
|||
|
||||
if (container == appletsLayout) {
|
||||
if (item.modelData) {
|
||||
root.model.setLocation(item.modelData.index, MobileShell.ApplicationListModel.Desktop);
|
||||
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.Desktop);
|
||||
}
|
||||
var pos = appletsLayout.mapFromItem(item, 0, 0);
|
||||
item.parent = appletsLayout;
|
||||
|
|
@ -288,9 +280,9 @@ Item {
|
|||
|
||||
return;
|
||||
} else if (container == favoriteStrip) {
|
||||
root.model.setLocation(item.modelData.index, MobileShell.ApplicationListModel.Favorites);
|
||||
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.Favorites);
|
||||
} else {
|
||||
root.model.setLocation(item.modelData.index, MobileShell.ApplicationListModel.Grid);
|
||||
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.None);
|
||||
}
|
||||
|
||||
var child = nearestChild(item, dragCenterX, dragCenterY, container);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@ import org.kde.kquickcontrolsaddons 2.0
|
|||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
import org.kde.kirigami 2.14 as Kirigami
|
||||
|
||||
Repeater {
|
||||
id: launcherRepeater
|
||||
model: MobileShell.FavoritesModel
|
||||
model: HomeScreenLib.DesktopModel
|
||||
|
||||
required property var homeScreenState
|
||||
|
||||
|
|
@ -51,15 +52,15 @@ Repeater {
|
|||
reservedSpaceForLabel: metrics.height
|
||||
property Item parentFromLocation: {
|
||||
switch (model.applicationLocation) {
|
||||
case MobileShell.ApplicationListModel.Favorites:
|
||||
return favoriteStrip.flow;
|
||||
case MobileShell.ApplicationListModel.Desktop:
|
||||
default:
|
||||
return appletsLayout;
|
||||
case HomeScreenLib.DesktopModel.Favorites:
|
||||
return favoriteStrip.flow;
|
||||
case HomeScreenLib.DesktopModel.Desktop:
|
||||
default:
|
||||
return appletsLayout;
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if (model.applicationLocation === MobileShell.ApplicationListModel.Desktop) {
|
||||
if (model.applicationLocation === HomeScreenLib.DesktopModel.Desktop) {
|
||||
appletsLayout.restoreItem(delegate);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,11 +116,10 @@ Repeater {
|
|||
onParentFromLocationChanged: {
|
||||
if (!launcherDragManager.active && parent != parentFromLocation) {
|
||||
parent = parentFromLocation;
|
||||
if (model.applicationLocation === MobileShell.ApplicationListModel.Favorites) {
|
||||
if (model.applicationLocation === HomeScreenLib.DesktopModel.Favorites) {
|
||||
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[index]);
|
||||
|
||||
} else if (model.applicationLocation === MobileShell.ApplicationListModel.Grid) {
|
||||
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - MobileShell.ApplicationListModel.favoriteCount)]);
|
||||
} else if (model.applicationLocation === HomeScreenLib.DesktopModel.None) {
|
||||
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - HomeScreenLib.DesktopModel.favoriteCount)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.kde.kirigami 2.10 as Kirigami
|
|||
|
||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
import "../private"
|
||||
|
||||
|
|
@ -37,11 +38,11 @@ AbstractAppDrawer {
|
|||
cellHeight: root.availableCellHeight
|
||||
|
||||
property int columns: Math.floor(root.contentWidth / cellWidth)
|
||||
property int rows: Math.ceil(model.count / columns)
|
||||
property int rows: Math.ceil(gridView.count / columns)
|
||||
|
||||
cacheBuffer: Math.max(0, rows * cellHeight)
|
||||
|
||||
model: MobileShell.ApplicationListModel
|
||||
model: HomeScreenLib.ApplicationListModel
|
||||
|
||||
delegate: DrawerGridDelegate {
|
||||
id: delegate
|
||||
|
|
@ -71,8 +72,8 @@ AbstractAppDrawer {
|
|||
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||
}
|
||||
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||
HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
HomeScreenLib.ApplicationListModel.runApplication(storageId);
|
||||
root.launched();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.kde.kirigami 2.10 as Kirigami
|
|||
|
||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
import "../private"
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ AbstractAppDrawer {
|
|||
|
||||
property int delegateHeight: PlasmaCore.Units.gridUnit * 3
|
||||
|
||||
model: MobileShell.ApplicationListModel
|
||||
model: HomeScreenLib.ApplicationListModel
|
||||
|
||||
delegate: DrawerListDelegate {
|
||||
id: delegate
|
||||
|
|
@ -63,8 +64,8 @@ AbstractAppDrawer {
|
|||
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||
}
|
||||
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||
HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
HomeScreenLib.ApplicationListModel.runApplication(storageId);
|
||||
root.launched();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
|||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
MobileShell.HomeScreen {
|
||||
id: root
|
||||
|
|
@ -31,24 +32,9 @@ MobileShell.HomeScreen {
|
|||
|
||||
property bool componentComplete: false
|
||||
|
||||
function recalculateMaxFavoriteCount() {
|
||||
if (!componentComplete) {
|
||||
return;
|
||||
}
|
||||
MobileShell.ApplicationListModel.maxFavoriteCount = Math.max(4, Math.floor(Math.min(width, height) / homescreen.homeScreenContents.favoriteStrip.cellWidth));
|
||||
}
|
||||
|
||||
onWidthChanged: recalculateMaxFavoriteCount()
|
||||
onHeightChanged: recalculateMaxFavoriteCount()
|
||||
|
||||
Component.onCompleted: {
|
||||
// ApplicationListModel doesn't have a plasmoid as is not the one that should be doing writing
|
||||
MobileShell.ApplicationListModel.loadApplications();
|
||||
MobileShell.FavoritesModel.applet = plasmoid;
|
||||
MobileShell.FavoritesModel.loadApplications();
|
||||
|
||||
componentComplete = true;
|
||||
recalculateMaxFavoriteCount()
|
||||
HomeScreenLib.ApplicationListModel.loadApplications();
|
||||
HomeScreenLib.DesktopModel.load();
|
||||
|
||||
// ensure the gestures work immediately on load
|
||||
forceActiveFocus();
|
||||
|
|
@ -115,7 +101,7 @@ MobileShell.HomeScreen {
|
|||
|
||||
// listen to app launch errors
|
||||
Connections {
|
||||
target: MobileShell.ApplicationListModel
|
||||
target: HomeScreenLib.ApplicationListModel
|
||||
function onLaunchError(msg) {
|
||||
MobileShell.HomeScreenControls.closeAppLaunchAnimation()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import org.kde.kquickcontrolsaddons 2.0
|
|||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
|
||||
|
||||
PC3.RoundButton {
|
||||
id: removeButton
|
||||
|
|
@ -55,7 +56,7 @@ PC3.RoundButton {
|
|||
ScriptAction {
|
||||
script: {
|
||||
appletsLayout.releaseSpace(delegate);
|
||||
MobileShell.FavoritesModel.removeFavorite(index);
|
||||
HomeScreenLib.DesktopModel.removeFavorite(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue