homescreens/halcyon: Port folder app list to QAbstractListModel

This commit is contained in:
Devin Lin 2022-07-12 22:28:40 -04:00
parent 92d9295995
commit d94888b5f3
4 changed files with 136 additions and 42 deletions

View file

@ -8,6 +8,7 @@
ApplicationFolder::ApplicationFolder(QObject *parent, QString name) ApplicationFolder::ApplicationFolder(QObject *parent, QString name)
: QObject{parent} : QObject{parent}
, m_name{name} , m_name{name}
, m_applicationFolderModel{nullptr}
{ {
} }
@ -64,64 +65,44 @@ QList<Application *> ApplicationFolder::appPreviews()
return previews; return previews;
} }
QList<Application *> ApplicationFolder::applications() ApplicationFolderModel *ApplicationFolder::applications()
{ {
return m_applications; return m_applicationFolderModel;
} }
void ApplicationFolder::setApplications(QList<Application *> applications) void ApplicationFolder::setApplications(QList<Application *> applications)
{ {
if (m_applicationFolderModel) {
m_applicationFolderModel->deleteLater();
}
m_applications = applications; m_applications = applications;
Q_EMIT applicationsChanged(); Q_EMIT applicationsChanged();
Q_EMIT applicationsReset();
Q_EMIT saveRequested(); Q_EMIT saveRequested();
m_applicationFolderModel = new ApplicationFolderModel{this};
} }
void ApplicationFolder::moveEntry(int fromRow, int toRow) void ApplicationFolder::moveEntry(int fromRow, int toRow)
{ {
if (fromRow < 0 || toRow < 0 || fromRow >= m_applications.length() || toRow >= m_applications.length() || fromRow == toRow) { if (m_applicationFolderModel) {
return; m_applicationFolderModel->moveEntry(fromRow, toRow);
} }
if (toRow > fromRow) {
++toRow;
}
if (toRow > fromRow) {
Application *app = m_applications.at(fromRow);
m_applications.insert(toRow, app);
m_applications.takeAt(fromRow);
} else {
Application *app = m_applications.takeAt(fromRow);
m_applications.insert(toRow, app);
}
Q_EMIT applicationsChanged();
Q_EMIT saveRequested();
} }
void ApplicationFolder::addApp(const QString &storageId, int row) void ApplicationFolder::addApp(const QString &storageId, int row)
{ {
if (row < 0 || row > m_applications.size()) { if (m_applicationFolderModel) {
return; m_applicationFolderModel->addApp(storageId, row);
}
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
Application *app = new Application(this, service);
m_applications.insert(row, app);
Q_EMIT applicationsChanged();
Q_EMIT saveRequested();
} }
} }
void ApplicationFolder::removeApp(int row) void ApplicationFolder::removeApp(int row)
{ {
if (row < 0 || row >= m_applications.size()) { if (m_applicationFolderModel) {
return; m_applicationFolderModel->removeApp(row);
} }
m_applications[row]->deleteLater();
m_applications.removeAt(row);
Q_EMIT applicationsChanged();
Q_EMIT saveRequested();
} }
void ApplicationFolder::moveAppOut(int row) void ApplicationFolder::moveAppOut(int row)
@ -133,3 +114,88 @@ void ApplicationFolder::moveAppOut(int row)
Q_EMIT moveAppOutRequested(m_applications[row]->storageId()); Q_EMIT moveAppOutRequested(m_applications[row]->storageId());
removeApp(row); removeApp(row);
} }
ApplicationFolderModel::ApplicationFolderModel(ApplicationFolder *folder)
: QAbstractListModel{folder}
, m_folder{folder}
{
}
int ApplicationFolderModel::rowCount(const QModelIndex &parent) const
{
return m_folder->m_applications.size();
}
QVariant ApplicationFolderModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
switch (role) {
case ApplicationRole:
return QVariant::fromValue(m_folder->m_applications.at(index.row()));
}
return QVariant();
}
QHash<int, QByteArray> ApplicationFolderModel::roleNames() const
{
return {{ApplicationRole, "application"}};
}
void ApplicationFolderModel::moveEntry(int fromRow, int toRow)
{
if (fromRow < 0 || toRow < 0 || fromRow >= m_folder->m_applications.length() || toRow >= m_folder->m_applications.length() || fromRow == toRow) {
return;
}
if (toRow > fromRow) {
++toRow;
}
beginMoveRows(QModelIndex(), fromRow, fromRow, QModelIndex(), toRow);
if (toRow > fromRow) {
Application *app = m_folder->m_applications.at(fromRow);
m_folder->m_applications.insert(toRow, app);
m_folder->m_applications.takeAt(fromRow);
} else {
Application *app = m_folder->m_applications.takeAt(fromRow);
m_folder->m_applications.insert(toRow, app);
}
endMoveRows();
Q_EMIT m_folder->applicationsChanged();
Q_EMIT m_folder->saveRequested();
}
void ApplicationFolderModel::addApp(const QString &storageId, int row)
{
if (row < 0 || row > m_folder->m_applications.size()) {
return;
}
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
beginInsertRows(QModelIndex(), row, row);
Application *app = new Application(this, service);
m_folder->m_applications.insert(row, app);
endInsertRows();
Q_EMIT m_folder->applicationsChanged();
Q_EMIT m_folder->saveRequested();
}
}
void ApplicationFolderModel::removeApp(int row)
{
if (row < 0 || row >= m_folder->m_applications.size()) {
return;
}
beginRemoveRows(QModelIndex(), row, row);
m_folder->m_applications[row]->deleteLater();
m_folder->m_applications.removeAt(row);
endRemoveRows();
Q_EMIT m_folder->applicationsChanged();
Q_EMIT m_folder->saveRequested();
}

View file

@ -5,6 +5,7 @@
#include "application.h" #include "application.h"
#include <QAbstractListModel>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@ -18,12 +19,14 @@
/** /**
* @short Object that represents an application folder on the main page. * @short Object that represents an application folder on the main page.
*/ */
class ApplicationFolderModel;
class ApplicationFolder : public QObject class ApplicationFolder : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QList<Application *> appPreviews READ appPreviews NOTIFY applicationsChanged) Q_PROPERTY(QList<Application *> appPreviews READ appPreviews NOTIFY applicationsChanged)
Q_PROPERTY(QList<Application *> applications READ applications NOTIFY applicationsChanged) Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset)
public: public:
ApplicationFolder(QObject *parent = nullptr, QString name = QString{}); ApplicationFolder(QObject *parent = nullptr, QString name = QString{});
@ -36,7 +39,7 @@ public:
QList<Application *> appPreviews(); QList<Application *> appPreviews();
QList<Application *> applications(); ApplicationFolderModel *applications();
void setApplications(QList<Application *> applications); void setApplications(QList<Application *> applications);
Q_INVOKABLE void moveEntry(int fromRow, int toRow); Q_INVOKABLE void moveEntry(int fromRow, int toRow);
@ -46,11 +49,37 @@ public:
Q_SIGNALS: Q_SIGNALS:
void nameChanged(); void nameChanged();
void applicationsChanged();
void saveRequested(); void saveRequested();
void moveAppOutRequested(const QString &storageId); void moveAppOutRequested(const QString &storageId);
void applicationsChanged();
void applicationsReset();
private: private:
QString m_name; QString m_name;
QList<Application *> m_applications; QList<Application *> m_applications;
ApplicationFolderModel *m_applicationFolderModel;
friend class ApplicationFolderModel;
};
class ApplicationFolderModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles { ApplicationRole = Qt::UserRole + 1 };
ApplicationFolderModel(ApplicationFolder *folder);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
void moveEntry(int fromRow, int toRow);
void addApp(const QString &storageId, int row);
void removeApp(int row);
private:
ApplicationFolder *m_folder;
friend class ApplicationFolder;
}; };

View file

@ -174,11 +174,10 @@ MobileShell.GridView {
model: root.folderModel model: root.folderModel
delegate: Item { delegate: Item {
id: delegateRoot id: delegateRoot
width: root.cellWidth width: root.cellWidth
height: root.cellHeight height: root.cellHeight
property var application: model.application
property int visualIndex: DelegateModel.itemsIndex property int visualIndex: DelegateModel.itemsIndex
DropArea { DropArea {
@ -196,7 +195,7 @@ MobileShell.GridView {
visualIndex: delegateRoot.visualIndex visualIndex: delegateRoot.visualIndex
isFolder: false isFolder: false
application: modelData application: model.application
menuActions: [ menuActions: [
Kirigami.Action { Kirigami.Action {

View file

@ -175,7 +175,7 @@ void PinnedModel::addAppToFolder(int appRow, int folderRow)
ApplicationFolder *folder = m_folders[folderRow]; ApplicationFolder *folder = m_folders[folderRow];
Application *app = m_applications[appRow]; Application *app = m_applications[appRow];
folder->addApp(app->storageId(), folder->applications().count()); folder->addApp(app->storageId(), folder->applications() ? folder->applications()->rowCount() : 0);
removeEntry(appRow); removeEntry(appRow);
} }