homescreen: Start refactoring and cleaning

fix
This commit is contained in:
Devin Lin 2022-06-17 00:48:53 -04:00
parent 25f36c4023
commit b41e1f2b8a
22 changed files with 500 additions and 625 deletions

View file

@ -17,8 +17,6 @@ set(mobileshellplugin_SRCS
components/direction.cpp components/direction.cpp
notifications/notificationthumbnailer.cpp notifications/notificationthumbnailer.cpp
notifications/notificationfilemenu.cpp notifications/notificationfilemenu.cpp
homescreen/applicationlistmodel.cpp
homescreen/favoritesmodel.cpp
taskswitcher/displaysmodel.cpp taskswitcher/displaysmodel.cpp
) )
if (QT_MAJOR_VERSION STREQUAL "5") if (QT_MAJOR_VERSION STREQUAL "5")

View file

@ -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"

View file

@ -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;
};

View file

@ -14,9 +14,6 @@
#include "notifications/notificationfilemenu.h" #include "notifications/notificationfilemenu.h"
#include "notifications/notificationthumbnailer.h" #include "notifications/notificationthumbnailer.h"
#include "homescreen/applicationlistmodel.h"
#include "homescreen/favoritesmodel.h"
#include "taskswitcher/displaysmodel.h" #include "taskswitcher/displaysmodel.h"
#include "mobileshellsettings.h" #include "mobileshellsettings.h"
@ -55,14 +52,6 @@ void MobileShellPlugin::registerTypes(const char *uri)
// components // components
qmlRegisterType<Direction>(uri, 1, 0, "Direction"); 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 // notifications
qmlRegisterType<NotificationThumbnailer>(uri, 1, 0, "NotificationThumbnailer"); qmlRegisterType<NotificationThumbnailer>(uri, 1, 0, "NotificationThumbnailer");
qmlRegisterType<NotificationFileMenu>(uri, 1, 0, "NotificationFileMenu"); qmlRegisterType<NotificationFileMenu>(uri, 1, 0, "NotificationFileMenu");

View file

@ -49,6 +49,10 @@ MouseArea { // use mousearea to ensure clicks don't go behind
MobileShell.HomeScreenControls.taskSwitcher.minimizeAll(); MobileShell.HomeScreenControls.taskSwitcher.minimizeAll();
} }
function close() {
visible = false;
}
// close when an app opens // close when an app opens
property bool windowActive: Window.active property bool windowActive: Window.active
onWindowActiveChanged: { onWindowActiveChanged: {

View file

@ -213,12 +213,4 @@ Item {
z: 999999 z: 999999
anchors.fill: parent anchors.fill: parent
} }
// listen to app launch errors
Connections {
target: MobileShell.ApplicationListModel
function onLaunchError(msg) {
MobileShell.HomeScreenControls.closeAppLaunchAnimation()
}
}
} }

View file

@ -3,6 +3,8 @@
set(homescreen_SRCS set(homescreen_SRCS
homescreen.cpp homescreen.cpp
desktopmodel.cpp
applicationlistmodel.cpp
) )
add_library(plasma_containment_phone_homescreen MODULE ${homescreen_SRCS}) add_library(plasma_containment_phone_homescreen MODULE ${homescreen_SRCS})

View file

@ -7,7 +7,6 @@
// Self // Self
#include "applicationlistmodel.h" #include "applicationlistmodel.h"
#include "../windowutil.h"
// Qt // Qt
#include <QByteArray> #include <QByteArray>
@ -19,6 +18,7 @@
// KDE // KDE
#include <KApplicationTrader> #include <KApplicationTrader>
#include <KConfigGroup>
#include <KIO/ApplicationLauncherJob> #include <KIO/ApplicationLauncherJob>
#include <KNotificationJobUiDelegate> #include <KNotificationJobUiDelegate>
#include <KService> #include <KService>
@ -30,10 +30,6 @@
#include <KWayland/Client/registry.h> #include <KWayland/Client/registry.h>
#include <KWayland/Client/surface.h> #include <KWayland/Client/surface.h>
#include <Plasma/Applet>
constexpr int MAX_FAVOURITES = 5;
ApplicationListModel::ApplicationListModel(QObject *parent) ApplicationListModel::ApplicationListModel(QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
{ {
@ -42,50 +38,49 @@ ApplicationListModel::ApplicationListModel(QObject *parent)
#else #else
connect(KSycoca::self(), &KSycoca::databaseChanged, this, &ApplicationListModel::sycocaDbChanged); connect(KSycoca::self(), &KSycoca::databaseChanged, this, &ApplicationListModel::sycocaDbChanged);
#endif #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; 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 QHash<int, QByteArray> ApplicationListModel::roleNames() const
{ {
return {{ApplicationNameRole, QByteArrayLiteral("applicationName")}, return {{ApplicationNameRole, QByteArrayLiteral("applicationName")},
{ApplicationIconRole, QByteArrayLiteral("applicationIcon")}, {ApplicationIconRole, QByteArrayLiteral("applicationIcon")},
{ApplicationStorageIdRole, QByteArrayLiteral("applicationStorageId")}, {ApplicationStorageIdRole, QByteArrayLiteral("applicationStorageId")},
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")}, {ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")}, {ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")},
{ApplicationRunningRole, QByteArrayLiteral("applicationRunning")}, {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() void ApplicationListModel::sycocaDbChanged()
{ {
m_applicationList.clear(); m_applicationList.clear();
loadApplications(); 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() void ApplicationListModel::loadApplications()
{ {
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc")); auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
@ -132,9 +122,7 @@ void ApplicationListModel::loadApplications()
m_applicationList.clear(); m_applicationList.clear();
QMap<int, ApplicationData> orderedList;
QList<ApplicationData> unorderedList; QList<ApplicationData> unorderedList;
QSet<QString> foundFavorites;
auto filter = [blacklist](const KService::Ptr &service) -> bool { auto filter = [blacklist](const KService::Ptr &service) -> bool {
if (service->noDisplay()) { if (service->noDisplay()) {
@ -162,45 +150,16 @@ void ApplicationListModel::loadApplications()
data.uniqueId = service->storageId(); data.uniqueId = service->storageId();
data.entryPath = service->exec(); data.entryPath = service->exec();
data.startupNotify = service->property(QStringLiteral("StartupNotify")).toBool(); 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); std::sort(unorderedList.begin(), unorderedList.end(), [](const ApplicationListModel::ApplicationData &a1, const ApplicationListModel::ApplicationData &a2) {
cfg->sync(); return a1.name.compare(a2.name, Qt::CaseInsensitive) < 0;
});
std::sort(unorderedList.begin(), unorderedList.end(), appNameLessThan);
m_applicationList << orderedList.values();
m_applicationList << unorderedList; m_applicationList << unorderedList;
endResetModel(); 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 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; return m_applicationList.at(index.row()).storageId;
case ApplicationEntryPathRole: case ApplicationEntryPathRole:
return m_applicationList.at(index.row()).entryPath; return m_applicationList.at(index.row()).entryPath;
case ApplicationOriginalRowRole:
return index.row();
case ApplicationStartupNotifyRole: case ApplicationStartupNotifyRole:
return m_applicationList.at(index.row()).startupNotify; return m_applicationList.at(index.row()).startupNotify;
case ApplicationLocationRole:
return m_applicationList.at(index.row()).location;
case ApplicationRunningRole: case ApplicationRunningRole:
return m_applicationList.at(index.row()).window != nullptr; return m_applicationList.at(index.row()).window != nullptr;
case ApplicationUniqueIdRole: case ApplicationUniqueIdRole:
return m_applicationList.at(index.row()).uniqueId; return m_applicationList.at(index.row()).uniqueId;
case ApplicationLocationRole:
return m_applicationList.at(index.row()).location;
default: default:
return QVariant(); 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 int ApplicationListModel::rowCount(const QModelIndex &parent) const
{ {
if (parent.isValid()) { if (parent.isValid()) {
@ -251,103 +200,6 @@ int ApplicationListModel::rowCount(const QModelIndex &parent) const
return m_applicationList.count(); 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) void ApplicationListModel::runApplication(const QString &storageId)
{ {
if (storageId.isEmpty()) { 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) void ApplicationListModel::setMinimizedDelegate(int row, QQuickItem *delegate)
{ {
if (row < 0 || row >= m_applicationList.count()) { if (row < 0 || row >= m_applicationList.count()) {

View file

@ -8,7 +8,6 @@
#pragma once #pragma once
// Qt // Qt
#include <PlasmaQuick/AppletQuickItem>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QList> #include <QList>
#include <QObject> #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 class ApplicationListModel : public QAbstractListModel
{ {
Q_OBJECT 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: public:
enum LauncherLocation { Grid = 0, Favorites, Desktop }; // this enum is solely used by DesktopModel
enum LauncherLocation { None = 0, Favorites, Desktop };
Q_ENUM(LauncherLocation) Q_ENUM(LauncherLocation)
struct ApplicationData { struct ApplicationData {
@ -48,9 +45,9 @@ public:
QString icon; QString icon;
QString storageId; QString storageId;
QString entryPath; QString entryPath;
LauncherLocation location = LauncherLocation::Grid;
bool startupNotify = true; bool startupNotify = true;
KWayland::Client::PlasmaWindow *window = nullptr; KWayland::Client::PlasmaWindow *window = nullptr;
LauncherLocation location = LauncherLocation::None; // only for DesktopModel
}; };
enum Roles { enum Roles {
@ -58,56 +55,23 @@ public:
ApplicationIconRole, ApplicationIconRole,
ApplicationStorageIdRole, ApplicationStorageIdRole,
ApplicationEntryPathRole, ApplicationEntryPathRole,
ApplicationOriginalRowRole,
ApplicationStartupNotifyRole, ApplicationStartupNotifyRole,
ApplicationLocationRole,
ApplicationRunningRole, ApplicationRunningRole,
ApplicationUniqueIdRole ApplicationUniqueIdRole,
ApplicationLocationRole // only valid for DesktopModel
}; };
ApplicationListModel(QObject *parent = nullptr); ApplicationListModel(QObject *parent = nullptr);
~ApplicationListModel() override; ~ApplicationListModel() override;
static ApplicationListModel *instance() static ApplicationListModel *instance();
{
static ApplicationListModel *model = new ApplicationListModel;
return model;
}
void loadSettings();
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; 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; 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; 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 virtual void loadApplications();
Q_INVOKABLE void runApplication(const QString &storageId);
Q_INVOKABLE void setMinimizedDelegate(int row, QQuickItem *delegate); Q_INVOKABLE void setMinimizedDelegate(int row, QQuickItem *delegate);
Q_INVOKABLE void unsetMinimizedDelegate(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); void windowCreated(KWayland::Client::PlasmaWindow *window);
Q_SIGNALS: Q_SIGNALS:
void countChanged();
void favoriteCountChanged();
void maxFavoriteCountChanged();
void appletChanged();
void launchError(const QString &msg); void launchError(const QString &msg);
protected: protected:
QList<ApplicationData> m_applicationList; QList<ApplicationData> m_applicationList;
PlasmaQuick::AppletQuickItem *m_applet = nullptr; KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
int m_maxFavoriteCount = 0;
QStringList m_appOrder;
QStringList m_favorites;
QSet<QString> m_desktopItems;
QHash<QString, int> m_appPositions;
}; };

View 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();
}
}

View 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;
};

View file

@ -1,19 +1,33 @@
/* // SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> // SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "homescreen.h" #include "homescreen.h"
#include <KWindowSystem> #include <KWindowSystem>
#include <QDebug> #include <QDebug>
#include <QQuickItem> #include <QQuickItem>
#include <QtQml> #include <QtQml>
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args) HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
: Plasma::Containment(parent, data, args) : Plasma::Containment{parent, data, args}
{ {
setHasConfigurationInterface(true); 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); connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
} }

View file

@ -1,12 +1,14 @@
/* // SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> // SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once #pragma once
#include <Plasma/Containment> #include <Plasma/Containment>
#include <QSortFilterProxyModel>
#include <applicationlistmodel.h>
#include <desktopmodel.h>
class HomeScreen : public Plasma::Containment class HomeScreen : public Plasma::Containment
{ {
@ -24,7 +26,4 @@ public:
Q_SIGNALS: Q_SIGNALS:
void showingDesktopChanged(bool showingDesktop); void showingDesktopChanged(bool showingDesktop);
private:
bool m_showAllApps = false;
}; };

View file

@ -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.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import "private" as Private import "private" as Private
@ -50,9 +51,9 @@ ContainmentLayoutManager.ItemContainer {
} }
if (!MobileShell.HomeScreenControls.taskSwitcherVisible) { if (!MobileShell.HomeScreenControls.taskSwitcherVisible) {
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate); HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
} else { } 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); delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, modelData.applicationName);
} }
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate); HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
MobileShell.ApplicationListModel.runApplication(modelData.applicationStorageId); HomeScreenLib.DesktopModel.runApplication(modelData.applicationStorageId);
} }
readonly property bool applicationRunning: model.applicationRunning readonly property bool applicationRunning: model.applicationRunning

View file

@ -20,6 +20,7 @@ import "appdrawer"
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager 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.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
Item { Item {
id: root id: root
@ -103,7 +104,7 @@ Item {
appletsLayout: contents.appletsLayout appletsLayout: contents.appletsLayout
visible: favoriteStrip.flow.children.length > 0 || contents.launcherDragManager.active || contents.containsDrag 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 { TapHandler {
target: favoriteStrip target: favoriteStrip

View file

@ -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.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import "private" as Private import "private" as Private
@ -52,6 +53,9 @@ DragDrop.DropArea {
property bool inAppletEditMode: false property bool inAppletEditMode: false
property var applicationListModel: HomeScreenLib.ApplicationListModel
property var desktopModel: HomeScreenLib.DesktopModel
Connections { Connections {
target: plasmoid target: plasmoid
function onEditModeChanged() { function onEditModeChanged() {
@ -67,7 +71,7 @@ DragDrop.DropArea {
onDragMove: { onDragMove: {
let posInFavorites = favoriteStrip.mapFromItem(this, event.x, event.y); let posInFavorites = favoriteStrip.mapFromItem(this, event.x, event.y);
if (posInFavorites.y > 0) { if (posInFavorites.y > 0) {
if (MobileShell.ApplicationListModel.favoriteCount >= MobileShell.ApplicationListModel.maxFavoriteCount ) { if (desktopModel.favoriteCount >= desktopModel.maxFavoriteCount) {
launcherDragManager.hideSpacer(); launcherDragManager.hideSpacer();
} else { } else {
launcherDragManager.showSpacerAtPos(event.x, event.y, favoriteStrip); launcherDragManager.showSpacerAtPos(event.x, event.y, favoriteStrip);
@ -110,12 +114,12 @@ DragDrop.DropArea {
let posInFavorites = favoriteStrip.flow.mapFromItem(this, event.x, event.y); let posInFavorites = favoriteStrip.flow.mapFromItem(this, event.x, event.y);
if (posInFavorites.y > 0) { if (posInFavorites.y > 0) {
if (MobileShell.ApplicationListModel.favoriteCount >= MobileShell.ApplicationListModel.maxFavoriteCount ) { if (desktopModel.favoriteCount >= desktopModel.maxFavoriteCount ) {
return; return;
} }
let pos = Math.min(MobileShell.FavoritesModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth)) let pos = Math.min(desktopModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
MobileShell.FavoritesModel.addFavorite(storageId, pos, MobileShell.ApplicationListModel.Favorites) desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Favorites)
let item = launcherRepeater.itemAt(pos); let item = launcherRepeater.itemAt(pos);
if (item) { if (item) {
@ -129,8 +133,8 @@ DragDrop.DropArea {
return; return;
} }
let pos = MobileShell.FavoritesModel.count; let pos = desktopModel.count;
MobileShell.FavoritesModel.addFavorite(storageId, pos, MobileShell.ApplicationListModel.Desktop) desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Desktop)
let item = launcherRepeater.itemAt(pos); let item = launcherRepeater.itemAt(pos);
event.accept(event.proposedAction); event.accept(event.proposedAction);
@ -230,4 +234,3 @@ DragDrop.DropArea {
} }
} }

View file

@ -6,8 +6,10 @@
import QtQuick 2.4 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.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
Item { Item {
id: root id: root
@ -16,7 +18,8 @@ Item {
property FavoriteStrip favoriteStrip property FavoriteStrip favoriteStrip
property ContainmentLayoutManager.ItemContainer currentlyDraggedDelegate property ContainmentLayoutManager.ItemContainer currentlyDraggedDelegate
property bool active property bool active
property QtObject model: MobileShell.ApplicationListModel
property var desktopModel: HomeScreenLib.DesktopModel
readonly property Item spacer: Item { readonly property Item spacer: Item {
width: favoriteStrip.cellWidth width: favoriteStrip.cellWidth
@ -41,15 +44,12 @@ Item {
var pos = favoriteStrip.flow.mapFromItem(delegate, 0, 0); var pos = favoriteStrip.flow.mapFromItem(delegate, 0, 0);
newRow = Math.floor((pos.x + dragCenterX) / delegate.width); newRow = Math.floor((pos.x + dragCenterX) / delegate.width);
//root.model.setLocation(delegate.modelData.index, MobileShell.ApplicationListModel.Favorites);
showSpacer(delegate, dragCenterX, dragCenterY); showSpacer(delegate, dragCenterX, dragCenterY);
root.model.moveItem(delegate.modelData.index, newRow); HomeScreenLib.DesktopModel.moveItem(delegate.modelData.index, newRow);
// Put it on desktop // Put it on desktop
} else { } else {
var pos = appletsLayout.mapFromItem(delegate, 0, 0); var pos = appletsLayout.mapFromItem(delegate, 0, 0);
//root.model.setLocation(delegate.modelData.index, MobileShell.ApplicationListModel.Desktop);
showSpacer(delegate, dragCenterX, dragCenterY); showSpacer(delegate, dragCenterX, dragCenterY);
return; return;
@ -162,8 +162,8 @@ Item {
if (!item.modelData) { if (!item.modelData) {
return appletsLayout; return appletsLayout;
} else if (favoriteStrip.contains(Qt.point(0,favoriteStrip.frame.mapFromItem(item, dragCenterX, dragCenterY).y)) } else if (favoriteStrip.contains(Qt.point(0,favoriteStrip.frame.mapFromItem(item, dragCenterX, dragCenterY).y))
&& (item.modelData.applicationLocation == MobileShell.ApplicationListModel.Favorites && (item.modelData.applicationLocation == HomeScreenLib.DesktopModel.Favorites
|| root.model.favoriteCount < root.model.maxFavoriteCount)) { || HomeScreenLib.DesktopModel.favoriteCount < HomeScreenLib.DesktopModel.maxFavoriteCount)) {
return favoriteStrip; return favoriteStrip;
} else { } else {
return appletsLayout; 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; return child;
} }
@ -277,7 +269,7 @@ Item {
if (container == appletsLayout) { if (container == appletsLayout) {
if (item.modelData) { 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); var pos = appletsLayout.mapFromItem(item, 0, 0);
item.parent = appletsLayout; item.parent = appletsLayout;
@ -288,9 +280,9 @@ Item {
return; return;
} else if (container == favoriteStrip) { } else if (container == favoriteStrip) {
root.model.setLocation(item.modelData.index, MobileShell.ApplicationListModel.Favorites); HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.Favorites);
} else { } 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); var child = nearestChild(item, dragCenterX, dragCenterY, container);

View file

@ -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.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.nanoshell 2.0 as NanoShell 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 import org.kde.kirigami 2.14 as Kirigami
Repeater { Repeater {
id: launcherRepeater id: launcherRepeater
model: MobileShell.FavoritesModel model: HomeScreenLib.DesktopModel
required property var homeScreenState required property var homeScreenState
@ -51,15 +52,15 @@ Repeater {
reservedSpaceForLabel: metrics.height reservedSpaceForLabel: metrics.height
property Item parentFromLocation: { property Item parentFromLocation: {
switch (model.applicationLocation) { switch (model.applicationLocation) {
case MobileShell.ApplicationListModel.Favorites: case HomeScreenLib.DesktopModel.Favorites:
return favoriteStrip.flow; return favoriteStrip.flow;
case MobileShell.ApplicationListModel.Desktop: case HomeScreenLib.DesktopModel.Desktop:
default: default:
return appletsLayout; return appletsLayout;
} }
} }
Component.onCompleted: { Component.onCompleted: {
if (model.applicationLocation === MobileShell.ApplicationListModel.Desktop) { if (model.applicationLocation === HomeScreenLib.DesktopModel.Desktop) {
appletsLayout.restoreItem(delegate); appletsLayout.restoreItem(delegate);
} }
} }
@ -115,11 +116,10 @@ Repeater {
onParentFromLocationChanged: { onParentFromLocationChanged: {
if (!launcherDragManager.active && parent != parentFromLocation) { if (!launcherDragManager.active && parent != parentFromLocation) {
parent = parentFromLocation; parent = parentFromLocation;
if (model.applicationLocation === MobileShell.ApplicationListModel.Favorites) { if (model.applicationLocation === HomeScreenLib.DesktopModel.Favorites) {
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[index]); MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[index]);
} else if (model.applicationLocation === HomeScreenLib.DesktopModel.None) {
} else if (model.applicationLocation === MobileShell.ApplicationListModel.Grid) { MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - HomeScreenLib.DesktopModel.favoriteCount)]);
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - MobileShell.ApplicationListModel.favoriteCount)]);
} }
} }
} }

View file

@ -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.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import "../private" import "../private"
@ -37,11 +38,11 @@ AbstractAppDrawer {
cellHeight: root.availableCellHeight cellHeight: root.availableCellHeight
property int columns: Math.floor(root.contentWidth / cellWidth) 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) cacheBuffer: Math.max(0, rows * cellHeight)
model: MobileShell.ApplicationListModel model: HomeScreenLib.ApplicationListModel
delegate: DrawerGridDelegate { delegate: DrawerGridDelegate {
id: delegate id: delegate
@ -71,8 +72,8 @@ AbstractAppDrawer {
Math.min(delegate.iconItem.width, delegate.iconItem.height)); Math.min(delegate.iconItem.width, delegate.iconItem.height));
} }
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate); HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ApplicationListModel.runApplication(storageId); HomeScreenLib.ApplicationListModel.runApplication(storageId);
root.launched(); root.launched();
} }
} }

View file

@ -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.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import "../private" import "../private"
@ -33,7 +34,7 @@ AbstractAppDrawer {
property int delegateHeight: PlasmaCore.Units.gridUnit * 3 property int delegateHeight: PlasmaCore.Units.gridUnit * 3
model: MobileShell.ApplicationListModel model: HomeScreenLib.ApplicationListModel
delegate: DrawerListDelegate { delegate: DrawerListDelegate {
id: delegate id: delegate
@ -63,8 +64,8 @@ AbstractAppDrawer {
Math.min(delegate.iconItem.width, delegate.iconItem.height)); Math.min(delegate.iconItem.width, delegate.iconItem.height));
} }
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate); HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ApplicationListModel.runApplication(storageId); HomeScreenLib.ApplicationListModel.runApplication(storageId);
root.launched(); root.launched();
} }
} }

View file

@ -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.components 3.0 as PlasmaComponents
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
MobileShell.HomeScreen { MobileShell.HomeScreen {
id: root id: root
@ -31,24 +32,9 @@ MobileShell.HomeScreen {
property bool componentComplete: false 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: { Component.onCompleted: {
// ApplicationListModel doesn't have a plasmoid as is not the one that should be doing writing HomeScreenLib.ApplicationListModel.loadApplications();
MobileShell.ApplicationListModel.loadApplications(); HomeScreenLib.DesktopModel.load();
MobileShell.FavoritesModel.applet = plasmoid;
MobileShell.FavoritesModel.loadApplications();
componentComplete = true;
recalculateMaxFavoriteCount()
// ensure the gestures work immediately on load // ensure the gestures work immediately on load
forceActiveFocus(); forceActiveFocus();
@ -115,7 +101,7 @@ MobileShell.HomeScreen {
// listen to app launch errors // listen to app launch errors
Connections { Connections {
target: MobileShell.ApplicationListModel target: HomeScreenLib.ApplicationListModel
function onLaunchError(msg) { function onLaunchError(msg) {
MobileShell.HomeScreenControls.closeAppLaunchAnimation() MobileShell.HomeScreenControls.closeAppLaunchAnimation()
} }

View file

@ -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.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
PC3.RoundButton { PC3.RoundButton {
id: removeButton id: removeButton
@ -55,7 +56,7 @@ PC3.RoundButton {
ScriptAction { ScriptAction {
script: { script: {
appletsLayout.releaseSpace(delegate); appletsLayout.releaseSpace(delegate);
MobileShell.FavoritesModel.removeFavorite(index); HomeScreenLib.DesktopModel.removeFavorite(index);
} }
} }
} }