From d94888b5f317eb81c59ad897087d08a7aa872401 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Tue, 12 Jul 2022 22:28:40 -0400 Subject: [PATCH] homescreens/halcyon: Port folder app list to QAbstractListModel --- .../homescreens/halcyon/applicationfolder.cpp | 136 +++++++++++++----- .../homescreens/halcyon/applicationfolder.h | 35 ++++- .../package/contents/ui/FolderGrid.qml | 5 +- .../homescreens/halcyon/pinnedmodel.cpp | 2 +- 4 files changed, 136 insertions(+), 42 deletions(-) diff --git a/containments/homescreens/halcyon/applicationfolder.cpp b/containments/homescreens/halcyon/applicationfolder.cpp index 2d2b5ab7..0c8fec3d 100644 --- a/containments/homescreens/halcyon/applicationfolder.cpp +++ b/containments/homescreens/halcyon/applicationfolder.cpp @@ -8,6 +8,7 @@ ApplicationFolder::ApplicationFolder(QObject *parent, QString name) : QObject{parent} , m_name{name} + , m_applicationFolderModel{nullptr} { } @@ -64,64 +65,44 @@ QList ApplicationFolder::appPreviews() return previews; } -QList ApplicationFolder::applications() +ApplicationFolderModel *ApplicationFolder::applications() { - return m_applications; + return m_applicationFolderModel; } void ApplicationFolder::setApplications(QList applications) { + if (m_applicationFolderModel) { + m_applicationFolderModel->deleteLater(); + } + m_applications = applications; Q_EMIT applicationsChanged(); + Q_EMIT applicationsReset(); Q_EMIT saveRequested(); + + m_applicationFolderModel = new ApplicationFolderModel{this}; } void ApplicationFolder::moveEntry(int fromRow, int toRow) { - if (fromRow < 0 || toRow < 0 || fromRow >= m_applications.length() || toRow >= m_applications.length() || fromRow == toRow) { - return; + if (m_applicationFolderModel) { + 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) { - if (row < 0 || row > m_applications.size()) { - return; - } - - if (KService::Ptr service = KService::serviceByStorageId(storageId)) { - Application *app = new Application(this, service); - m_applications.insert(row, app); - Q_EMIT applicationsChanged(); - Q_EMIT saveRequested(); + if (m_applicationFolderModel) { + m_applicationFolderModel->addApp(storageId, row); } } void ApplicationFolder::removeApp(int row) { - if (row < 0 || row >= m_applications.size()) { - return; + if (m_applicationFolderModel) { + m_applicationFolderModel->removeApp(row); } - - m_applications[row]->deleteLater(); - m_applications.removeAt(row); - Q_EMIT applicationsChanged(); - Q_EMIT saveRequested(); } void ApplicationFolder::moveAppOut(int row) @@ -133,3 +114,88 @@ void ApplicationFolder::moveAppOut(int row) Q_EMIT moveAppOutRequested(m_applications[row]->storageId()); 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 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(); +} diff --git a/containments/homescreens/halcyon/applicationfolder.h b/containments/homescreens/halcyon/applicationfolder.h index 63a297d5..d686eb00 100644 --- a/containments/homescreens/halcyon/applicationfolder.h +++ b/containments/homescreens/halcyon/applicationfolder.h @@ -5,6 +5,7 @@ #include "application.h" +#include #include #include @@ -18,12 +19,14 @@ /** * @short Object that represents an application folder on the main page. */ + +class ApplicationFolderModel; class ApplicationFolder : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QList appPreviews READ appPreviews NOTIFY applicationsChanged) - Q_PROPERTY(QList applications READ applications NOTIFY applicationsChanged) + Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset) public: ApplicationFolder(QObject *parent = nullptr, QString name = QString{}); @@ -36,7 +39,7 @@ public: QList appPreviews(); - QList applications(); + ApplicationFolderModel *applications(); void setApplications(QList applications); Q_INVOKABLE void moveEntry(int fromRow, int toRow); @@ -46,11 +49,37 @@ public: Q_SIGNALS: void nameChanged(); - void applicationsChanged(); void saveRequested(); void moveAppOutRequested(const QString &storageId); + void applicationsChanged(); + void applicationsReset(); private: QString m_name; QList 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 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; }; diff --git a/containments/homescreens/halcyon/package/contents/ui/FolderGrid.qml b/containments/homescreens/halcyon/package/contents/ui/FolderGrid.qml index 55b8f532..aea9a4c3 100644 --- a/containments/homescreens/halcyon/package/contents/ui/FolderGrid.qml +++ b/containments/homescreens/halcyon/package/contents/ui/FolderGrid.qml @@ -174,11 +174,10 @@ MobileShell.GridView { model: root.folderModel delegate: Item { - id: delegateRoot + id: delegateRoot width: root.cellWidth height: root.cellHeight - property var application: model.application property int visualIndex: DelegateModel.itemsIndex DropArea { @@ -196,7 +195,7 @@ MobileShell.GridView { visualIndex: delegateRoot.visualIndex isFolder: false - application: modelData + application: model.application menuActions: [ Kirigami.Action { diff --git a/containments/homescreens/halcyon/pinnedmodel.cpp b/containments/homescreens/halcyon/pinnedmodel.cpp index d234f21d..aaaa7700 100644 --- a/containments/homescreens/halcyon/pinnedmodel.cpp +++ b/containments/homescreens/halcyon/pinnedmodel.cpp @@ -175,7 +175,7 @@ void PinnedModel::addAppToFolder(int appRow, int folderRow) ApplicationFolder *folder = m_folders[folderRow]; Application *app = m_applications[appRow]; - folder->addApp(app->storageId(), folder->applications().count()); + folder->addApp(app->storageId(), folder->applications() ? folder->applications()->rowCount() : 0); removeEntry(appRow); }