diff --git a/containments/homescreens/folio/applicationlistmodel.cpp b/containments/homescreens/folio/applicationlistmodel.cpp index c3953239..89b0f25e 100644 --- a/containments/homescreens/folio/applicationlistmodel.cpp +++ b/containments/homescreens/folio/applicationlistmodel.cpp @@ -80,17 +80,17 @@ void ApplicationListModel::load() m_delegates.clear(); - QList unorderedList; + QList unorderedList; const KService::List apps = KApplicationTrader::query(filter); for (const KService::Ptr &service : apps) { - FolioApplication *app = new FolioApplication{m_homeScreen, service}; - FolioDelegate *delegate = new FolioDelegate{app, m_homeScreen}; + FolioApplication::Ptr app = std::make_shared(m_homeScreen, service); + FolioDelegate::Ptr delegate = std::make_shared(app, m_homeScreen); unorderedList << delegate; } - std::sort(unorderedList.begin(), unorderedList.end(), [](FolioDelegate *a1, FolioDelegate *a2) { + std::sort(unorderedList.begin(), unorderedList.end(), [](FolioDelegate::Ptr &a1, FolioDelegate::Ptr &a2) { return a1->application()->name().compare(a2->application()->name(), Qt::CaseInsensitive) < 0; }); @@ -105,12 +105,12 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const return QVariant(); } - FolioDelegate *delegate = m_delegates.at(index.row()); + FolioDelegate::Ptr delegate = m_delegates.at(index.row()); switch (role) { case Qt::DisplayRole: case DelegateRole: - return QVariant::fromValue(delegate); + return QVariant::fromValue(delegate.get()); case NameRole: if (!delegate->application()) { return QVariant(); diff --git a/containments/homescreens/folio/applicationlistmodel.h b/containments/homescreens/folio/applicationlistmodel.h index 5e3a0ed0..0b3534bb 100644 --- a/containments/homescreens/folio/applicationlistmodel.h +++ b/containments/homescreens/folio/applicationlistmodel.h @@ -43,8 +43,8 @@ public Q_SLOTS: protected: HomeScreen *m_homeScreen{nullptr}; - QList m_delegates; + QList> m_delegates; QTimer *m_reloadAppsTimer{nullptr}; }; diff --git a/containments/homescreens/folio/dragstate.cpp b/containments/homescreens/folio/dragstate.cpp index 4947ae7b..6149663b 100644 --- a/containments/homescreens/folio/dragstate.cpp +++ b/containments/homescreens/folio/dragstate.cpp @@ -109,12 +109,17 @@ void DelegateDragPosition::setFolderPosition(int folderPosition) } } -FolioApplicationFolder *DelegateDragPosition::folder() const +FolioApplicationFolder::Ptr DelegateDragPosition::folder() const { return m_folder; } -void DelegateDragPosition::setFolder(FolioApplicationFolder *folder) +FolioApplicationFolder *DelegateDragPosition::folderRaw() const +{ + return m_folder.get(); +} + +void DelegateDragPosition::setFolder(FolioApplicationFolder::Ptr folder) { if (m_folder != folder) { m_folder = folder; @@ -197,12 +202,17 @@ DelegateDragPosition *DragState::startPosition() const return m_startPosition; } -FolioDelegate *DragState::dropDelegate() const +FolioDelegate::Ptr DragState::dropDelegate() const { return m_dropDelegate; } -void DragState::setDropDelegate(FolioDelegate *dropDelegate) +FolioDelegate *DragState::dropDelegateRaw() const +{ + return m_dropDelegate.get(); +} + +void DragState::setDropDelegate(FolioDelegate::Ptr dropDelegate) { m_dropDelegate = dropDelegate; Q_EMIT dropDelegateChanged(); @@ -266,7 +276,7 @@ void DragState::onDelegateDragPositionOverFolderViewChanged() qreal x = getPointerX(); qreal y = getPointerY(); - auto *folder = m_state->currentFolder(); + FolioApplicationFolder::Ptr folder = m_state->currentFolder(); if (!folder) { return; } @@ -370,7 +380,7 @@ void DragState::onDelegateDragPositionOverFavouritesChanged() // start folder open timer if hovering over a folder // get delegate being hovered over - FolioDelegate *delegate = favouritesModel->getEntryAt(dropIndex); + FolioDelegate::Ptr delegate = favouritesModel->getEntryAt(dropIndex); // check delegate is a folder and the drop delegate is an app if (delegate && delegate->type() == FolioDelegate::Folder && m_dropDelegate && m_dropDelegate->type() == FolioDelegate::Application) { @@ -430,7 +440,7 @@ void DragState::onDelegateDragPositionOverPageViewChanged() PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page); if (pageModel) { // get delegate being hovered over - FolioDelegate *delegate = pageModel->getDelegate(row, column); + FolioDelegate::Ptr delegate = pageModel->getDelegate(row, column); // check delegate is a folder and the drop delegate is an app if (delegate && delegate->type() == FolioDelegate::Folder && m_dropDelegate && m_dropDelegate->type() == FolioDelegate::Application) { @@ -495,8 +505,8 @@ void DragState::onDelegateDragFromAppDrawerStarted(QString storageId) { // fetch delegate at start position if (KService::Ptr service = KService::serviceByStorageId(storageId)) { - FolioApplication *app = new FolioApplication{m_homeScreen, service}; - setDropDelegate(new FolioDelegate{app, m_homeScreen}); + FolioApplication::Ptr app = std::make_shared(m_homeScreen, service); + setDropDelegate(std::make_shared(app, m_homeScreen)); } else { setDropDelegate(nullptr); } @@ -511,7 +521,7 @@ void DragState::onDelegateDragFromFolderStarted(FolioApplicationFolder *folder, setDropDelegate(folder->applications()->getDelegate(position)); // set start location - m_startPosition->setFolder(folder); + m_startPosition->setFolder(folder->shared_from_this()); m_startPosition->setFolderPosition(position); m_startPosition->setLocation(DelegateDragPosition::Folder); } @@ -520,8 +530,8 @@ void DragState::onDelegateDragFromWidgetListStarted(QString appletPluginId) { // default widget has dimensions of 1x1, and id of -1 m_createdAppletPluginId = appletPluginId; - FolioWidget *widget = new FolioWidget{m_homeScreen, -1, 1, 1}; - setDropDelegate(new FolioDelegate{widget, m_homeScreen}); + FolioWidget::Ptr widget = std::make_shared(m_homeScreen, -1, 1, 1); + setDropDelegate(std::make_shared(widget, m_homeScreen)); // set start location m_startPosition->setLocation(DelegateDragPosition::WidgetList); @@ -619,7 +629,7 @@ void DragState::onOpenFolderTimerFinished() return; } - FolioApplicationFolder *folder = nullptr; + FolioApplicationFolder::Ptr folder = nullptr; QPointF screenPosition; switch (m_candidateDropPosition->location()) { @@ -631,7 +641,7 @@ void DragState::onOpenFolderTimerFinished() } // get delegate being hovered over - FolioDelegate *delegate = page->getDelegate(m_candidateDropPosition->pageRow(), m_candidateDropPosition->pageColumn()); + FolioDelegate::Ptr delegate = page->getDelegate(m_candidateDropPosition->pageRow(), m_candidateDropPosition->pageColumn()); if (!delegate || delegate->type() != FolioDelegate::Folder) { return; } @@ -643,7 +653,7 @@ void DragState::onOpenFolderTimerFinished() } case DelegateDragPosition::Favourites: { // get delegate being hovered over in favourites bar - FolioDelegate *delegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition()); + FolioDelegate::Ptr delegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition()); if (!delegate || delegate->type() != FolioDelegate::Folder) { return; } @@ -657,7 +667,7 @@ void DragState::onOpenFolderTimerFinished() } // open the folder - m_state->openFolder(screenPosition.x(), screenPosition.y(), folder); + m_state->openFolder(screenPosition.x(), screenPosition.y(), folder.get()); } void DragState::onLeaveFolderTimerFinished() @@ -678,7 +688,7 @@ void DragState::onChangeFolderPageTimerFinished() return; } - auto *folder = m_state->currentFolder(); + FolioApplicationFolder::Ptr folder = m_state->currentFolder(); qreal x = getPointerX(); qreal y = getPointerY(); @@ -714,7 +724,7 @@ void DragState::onFolderInsertBetweenTimerFinished() return; } - auto *folder = m_state->currentFolder(); + FolioApplicationFolder::Ptr folder = m_state->currentFolder(); // update the candidate drop position m_candidateDropPosition->setFolder(folder); @@ -782,10 +792,10 @@ bool DragState::createDropPositionDelegate() int column = m_candidateDropPosition->pageColumn(); // delegate to add - FolioPageDelegate *delegate = new FolioPageDelegate{row, column, m_dropDelegate, m_homeScreen}; + FolioPageDelegate::Ptr delegate = std::make_shared(row, column, m_dropDelegate, m_homeScreen); // delegate that exists at the drop position - FolioPageDelegate *existingDelegate = page->getDelegate(row, column); + FolioPageDelegate::Ptr existingDelegate = page->getDelegate(row, column); // if a delegate already exists at the spot, check if we can insert/create a folder if (existingDelegate) { @@ -801,10 +811,10 @@ bool DragState::createDropPositionDelegate() } else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) { // create a folder from the two apps - FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME); + FolioApplicationFolder::Ptr folder = std::make_shared(m_homeScreen, DEFAULT_FOLDER_NAME); folder->addDelegate(delegate, 0); folder->addDelegate(existingDelegate, 0); - FolioPageDelegate *folderDelegate = new FolioPageDelegate{row, column, folder, m_homeScreen}; + FolioPageDelegate::Ptr folderDelegate = std::make_shared(row, column, folder, m_homeScreen); page->removeDelegate(row, column); page->addDelegate(folderDelegate); @@ -828,7 +838,7 @@ bool DragState::createDropPositionDelegate() } case DelegateDragPosition::Favourites: { // delegate that exists at the drop position - FolioDelegate *existingDelegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition()); + FolioDelegate::Ptr existingDelegate = m_homeScreen->favouritesModel()->getEntryAt(m_candidateDropPosition->favouritesPosition()); // if a delegate already exists at the spot, check if we can insert/create a folder if (existingDelegate) { @@ -844,10 +854,10 @@ bool DragState::createDropPositionDelegate() } else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) { // create a folder from the two apps - FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME); + FolioApplicationFolder::Ptr folder = std::make_shared(m_homeScreen, DEFAULT_FOLDER_NAME); folder->addDelegate(m_dropDelegate, 0); folder->addDelegate(existingDelegate, 0); - FolioDelegate *folderDelegate = new FolioDelegate{folder, m_homeScreen}; + FolioDelegate::Ptr folderDelegate = std::make_shared(folder, m_homeScreen); m_homeScreen->favouritesModel()->removeEntry(m_candidateDropPosition->favouritesPosition()); m_homeScreen->favouritesModel()->addEntry(m_candidateDropPosition->favouritesPosition(), folderDelegate); @@ -878,7 +888,7 @@ bool DragState::createDropPositionDelegate() break; } case DelegateDragPosition::Folder: { - auto *folder = m_candidateDropPosition->folder(); + FolioApplicationFolder::Ptr folder = m_candidateDropPosition->folder(); if (!folder) { break; } diff --git a/containments/homescreens/folio/dragstate.h b/containments/homescreens/folio/dragstate.h index 3822424b..32a0d82e 100644 --- a/containments/homescreens/folio/dragstate.h +++ b/containments/homescreens/folio/dragstate.h @@ -23,7 +23,7 @@ class DelegateDragPosition : public QObject Q_PROPERTY(int pageColumn READ pageColumn NOTIFY pageColumnChanged) Q_PROPERTY(int favouritesPosition READ favouritesPosition NOTIFY favouritesPositionChanged) Q_PROPERTY(int folderPosition READ folderPosition NOTIFY folderPositionChanged) - Q_PROPERTY(FolioApplicationFolder *folder READ folder NOTIFY folderChanged) + Q_PROPERTY(FolioApplicationFolder *folder READ folderRaw NOTIFY folderChanged) public: enum Location { Pages, Favourites, AppDrawer, Folder, WidgetList }; @@ -53,8 +53,9 @@ public: void setFolderPosition(int folderPosition); // TODO: what if the folder becomes invalid? we need to clear it - FolioApplicationFolder *folder() const; - void setFolder(FolioApplicationFolder *folder); + std::shared_ptr folder() const; + FolioApplicationFolder *folderRaw() const; + void setFolder(std::shared_ptr folder); Q_SIGNALS: void locationChanged(); @@ -72,7 +73,7 @@ private: int m_pageColumn{0}; int m_favouritesPosition{0}; int m_folderPosition{0}; - FolioApplicationFolder *m_folder{nullptr}; + std::shared_ptr m_folder{nullptr}; }; Q_DECLARE_METATYPE(DelegateDragPosition); @@ -82,15 +83,17 @@ class DragState : public QObject Q_OBJECT Q_PROPERTY(DelegateDragPosition *candidateDropPosition READ candidateDropPosition CONSTANT) Q_PROPERTY(DelegateDragPosition *startPosition READ startPosition CONSTANT) - Q_PROPERTY(FolioDelegate *dropDelegate READ dropDelegate NOTIFY dropDelegateChanged) + Q_PROPERTY(FolioDelegate *dropDelegate READ dropDelegateRaw NOTIFY dropDelegateChanged) public: DragState(HomeScreenState *state = nullptr, HomeScreen *parent = nullptr); DelegateDragPosition *candidateDropPosition() const; DelegateDragPosition *startPosition() const; - FolioDelegate *dropDelegate() const; - void setDropDelegate(FolioDelegate *dropDelegate); + + std::shared_ptr dropDelegate() const; + FolioDelegate *dropDelegateRaw() const; + void setDropDelegate(std::shared_ptr dropDelegate); Q_SIGNALS: void dropDelegateChanged(); @@ -157,7 +160,7 @@ private: int m_favouritesInsertBetweenIndex{0}; // the delegate that is being dropped - FolioDelegate *m_dropDelegate{nullptr}; + std::shared_ptr m_dropDelegate{nullptr}; // where we are hovering over, potentially to drop the delegate DelegateDragPosition *const m_candidateDropPosition{nullptr}; diff --git a/containments/homescreens/folio/favouritesmodel.cpp b/containments/homescreens/folio/favouritesmodel.cpp index cfdf66f3..35fb6079 100644 --- a/containments/homescreens/folio/favouritesmodel.cpp +++ b/containments/homescreens/folio/favouritesmodel.cpp @@ -40,7 +40,7 @@ QVariant FavouritesModel::data(const QModelIndex &index, int role) const switch (role) { case DelegateRole: - return QVariant::fromValue(m_delegates.at(index.row()).delegate); + return QVariant::fromValue(m_delegates.at(index.row()).delegate.get()); } return QVariant(); @@ -90,7 +90,7 @@ void FavouritesModel::moveEntry(int fromRow, int toRow) save(); } -bool FavouritesModel::canAddEntry(int row, FolioDelegate *delegate) +bool FavouritesModel::canAddEntry(int row, FolioDelegate::Ptr delegate) { if (!delegate) { return false; @@ -103,7 +103,7 @@ bool FavouritesModel::canAddEntry(int row, FolioDelegate *delegate) return true; } -bool FavouritesModel::addEntry(int row, FolioDelegate *delegate) +bool FavouritesModel::addEntry(int row, FolioDelegate::Ptr delegate) { if (!canAddEntry(row, delegate)) { return false; @@ -129,7 +129,7 @@ bool FavouritesModel::addEntry(int row, FolioDelegate *delegate) return true; } -FolioDelegate *FavouritesModel::getEntryAt(int row) +FolioDelegate::Ptr FavouritesModel::getEntryAt(int row) { if (row < 0 || row >= m_delegates.size()) { return nullptr; @@ -186,12 +186,12 @@ void FavouritesModel::setGhostEntry(int row) // if it doesn't, add a new empty delegate if (!found) { - FolioDelegate *ghost = new FolioDelegate{m_homeScreen}; + FolioDelegate::Ptr ghost = std::make_shared(m_homeScreen); addEntry(row, ghost); } } -void FavouritesModel::replaceGhostEntry(FolioDelegate *delegate) +void FavouritesModel::replaceGhostEntry(FolioDelegate::Ptr delegate) { for (int i = 0; i < m_delegates.size(); i++) { if (m_delegates[i].delegate->type() == FolioDelegate::None) { @@ -221,7 +221,7 @@ QJsonArray FavouritesModel::exportToJson() { QJsonArray arr; for (int i = 0; i < m_delegates.size(); i++) { - FolioDelegate *delegate = m_delegates[i].delegate; + FolioDelegate::Ptr delegate = m_delegates[i].delegate; // if this delegate is empty, ignore it if (!delegate || delegate->type() == FolioDelegate::None) { @@ -264,7 +264,7 @@ void FavouritesModel::loadFromJson(QJsonArray arr) for (QJsonValueRef r : arr) { QJsonObject obj = r.toObject(); - FolioDelegate *delegate = FolioDelegate::fromJson(obj, m_homeScreen); + FolioDelegate::Ptr delegate = FolioDelegate::fromJson(obj, m_homeScreen); if (delegate) { connectSaveRequests(delegate); @@ -275,10 +275,10 @@ void FavouritesModel::loadFromJson(QJsonArray arr) endResetModel(); } -void FavouritesModel::connectSaveRequests(FolioDelegate *delegate) +void FavouritesModel::connectSaveRequests(FolioDelegate::Ptr delegate) { if (delegate->type() == FolioDelegate::Folder && delegate->folder()) { - connect(delegate->folder(), &FolioApplicationFolder::saveRequested, this, &FavouritesModel::save); + connect(delegate->folder().get(), &FolioApplicationFolder::saveRequested, this, &FavouritesModel::save); } } diff --git a/containments/homescreens/folio/favouritesmodel.h b/containments/homescreens/folio/favouritesmodel.h index 1ff88b9e..1f3025a3 100644 --- a/containments/homescreens/folio/favouritesmodel.h +++ b/containments/homescreens/folio/favouritesmodel.h @@ -20,7 +20,7 @@ class HomeScreen; class FolioDelegate; struct FavouritesDelegate { - FolioDelegate *delegate; + std::shared_ptr delegate; qreal xPosition; }; @@ -41,9 +41,9 @@ public: Q_INVOKABLE void removeEntry(int row); void moveEntry(int fromRow, int toRow); - bool canAddEntry(int row, FolioDelegate *delegate); - bool addEntry(int row, FolioDelegate *delegate); - FolioDelegate *getEntryAt(int row); + bool canAddEntry(int row, std::shared_ptr delegate); + bool addEntry(int row, std::shared_ptr delegate); + std::shared_ptr getEntryAt(int row); // whether the dock is full, we can't add any more items bool isFull() const; @@ -53,7 +53,7 @@ public: // invisible - existing delegate looks like it doesn't exist int getGhostEntryPosition(); void setGhostEntry(int row); - void replaceGhostEntry(FolioDelegate *delegate); + void replaceGhostEntry(std::shared_ptr delegate); void deleteGhostEntry(); // whether the position given is in between 2 delegates, or at the edge. @@ -71,7 +71,7 @@ public: void loadFromJson(QJsonArray arr); private: - void connectSaveRequests(FolioDelegate *delegate); + void connectSaveRequests(std::shared_ptr delegate); // get the x (or y) position where delegates start being placed qreal getDelegateRowStartPos() const; diff --git a/containments/homescreens/folio/folioapplication.cpp b/containments/homescreens/folio/folioapplication.cpp index 3edd8b7b..40c3ccbf 100644 --- a/containments/homescreens/folio/folioapplication.cpp +++ b/containments/homescreens/folio/folioapplication.cpp @@ -35,11 +35,11 @@ FolioApplication::FolioApplication(HomeScreen *parent, KService::Ptr service) }); } -FolioApplication *FolioApplication::fromJson(QJsonObject &obj, HomeScreen *parent) +FolioApplication::Ptr FolioApplication::fromJson(QJsonObject &obj, HomeScreen *parent) { QString storageId = obj[QStringLiteral("storageId")].toString(); if (KService::Ptr service = KService::serviceByStorageId(storageId)) { - return new FolioApplication(parent, service); + return std::make_shared(parent, service); } return nullptr; } diff --git a/containments/homescreens/folio/folioapplication.h b/containments/homescreens/folio/folioapplication.h index 33fb1005..4193c078 100644 --- a/containments/homescreens/folio/folioapplication.h +++ b/containments/homescreens/folio/folioapplication.h @@ -23,7 +23,7 @@ class HomeScreen; /** * @short Object that represents an application. */ -class FolioApplication : public QObject +class FolioApplication : public QObject, public std::enable_shared_from_this { Q_OBJECT Q_PROPERTY(bool running READ running NOTIFY windowChanged) @@ -32,9 +32,11 @@ class FolioApplication : public QObject Q_PROPERTY(QString storageId READ storageId NOTIFY storageIdChanged) public: + typedef std::shared_ptr Ptr; + FolioApplication(HomeScreen *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer{nullptr}); - static FolioApplication *fromJson(QJsonObject &obj, HomeScreen *parent); // may return nullptr + static FolioApplication::Ptr fromJson(QJsonObject &obj, HomeScreen *parent); // may return nullptr QJsonObject toJson() const; bool running() const; diff --git a/containments/homescreens/folio/folioapplicationfolder.cpp b/containments/homescreens/folio/folioapplicationfolder.cpp index e597ab76..d697dc82 100644 --- a/containments/homescreens/folio/folioapplicationfolder.cpp +++ b/containments/homescreens/folio/folioapplicationfolder.cpp @@ -15,17 +15,17 @@ FolioApplicationFolder::FolioApplicationFolder(HomeScreen *parent, QString name) { } -FolioApplicationFolder *FolioApplicationFolder::fromJson(QJsonObject &obj, HomeScreen *parent) +FolioApplicationFolder::Ptr FolioApplicationFolder::fromJson(QJsonObject &obj, HomeScreen *parent) { QString name = obj[QStringLiteral("name")].toString(); - QList apps; + QList apps; for (auto storageId : obj[QStringLiteral("apps")].toArray()) { if (KService::Ptr service = KService::serviceByStorageId(storageId.toString())) { - apps.append(new FolioApplication(parent, service)); + apps.append(std::make_shared(parent, service)); } } - FolioApplicationFolder *folder = new FolioApplicationFolder(parent, name); + FolioApplicationFolder::Ptr folder = std::make_shared(parent, name); folder->setApplications(apps); return folder; } @@ -69,7 +69,7 @@ QList FolioApplicationFolder::appPreviews() if (!m_delegates[i].delegate->application()) { continue; } - previews.push_back(m_delegates[i].delegate->application()); + previews.push_back(m_delegates[i].delegate->application().get()); } return previews; } @@ -79,15 +79,15 @@ ApplicationFolderModel *FolioApplicationFolder::applications() return m_applicationFolderModel; } -void FolioApplicationFolder::setApplications(QList applications) +void FolioApplicationFolder::setApplications(QList applications) { if (m_applicationFolderModel) { m_applicationFolderModel->deleteLater(); } m_delegates.clear(); - for (auto *app : applications) { - m_delegates.append({new FolioDelegate{app, m_homeScreen}, 0, 0}); + for (FolioApplication::Ptr app : applications) { + m_delegates.append({FolioDelegate::Ptr{new FolioDelegate{app, m_homeScreen}}, 0, 0, 0}); } m_applicationFolderModel = new ApplicationFolderModel{this}; m_applicationFolderModel->evaluateDelegateIndexes(); @@ -102,7 +102,7 @@ void FolioApplicationFolder::moveEntry(int fromRow, int toRow) m_applicationFolderModel->moveEntry(fromRow, toRow); } -bool FolioApplicationFolder::addDelegate(FolioDelegate *delegate, int row) +bool FolioApplicationFolder::addDelegate(FolioDelegate::Ptr delegate, int row) { return m_applicationFolderModel->addDelegate(delegate, row); } @@ -122,11 +122,11 @@ bool FolioApplicationFolder::isDropPositionOutside(qreal x, qreal y) return m_applicationFolderModel->isDropPositionOutside(x, y); } -ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *folder) - : QAbstractListModel{folder} - , m_folder{folder} +ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *parent) + : QAbstractListModel{parent} + , m_folder{parent} { - HomeScreenState *homeScreenState = folder->m_homeScreen->homeScreenState(); + HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState(); connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() { evaluateDelegateIndexes(); }); @@ -166,7 +166,7 @@ QVariant ApplicationFolderModel::data(const QModelIndex &index, int role) const switch (role) { case DelegateRole: - return QVariant::fromValue(m_folder->m_delegates.at(index.row()).delegate); + return QVariant::fromValue(m_folder->m_delegates.at(index.row()).delegate.get()); case columnIndexRole: return QVariant::fromValue(m_folder->m_delegates.at(index.row()).columnIndex); case rowIndexRole: @@ -183,7 +183,7 @@ QHash ApplicationFolderModel::roleNames() const return {{DelegateRole, "delegate"}, {columnIndexRole, "columnIndex"}, {rowIndexRole, "rowIndex"}, {pageIndexRole, "pageIndex"}}; } -FolioDelegate *ApplicationFolderModel::getDelegate(int index) +FolioDelegate::Ptr ApplicationFolderModel::getDelegate(int index) { if (index < 0 || index >= m_folder->m_delegates.size()) { return nullptr; @@ -217,7 +217,7 @@ void ApplicationFolderModel::moveEntry(int fromRow, int toRow) Q_EMIT m_folder->saveRequested(); } -bool ApplicationFolderModel::canAddDelegate(FolioDelegate *delegate, int index) +bool ApplicationFolderModel::canAddDelegate(FolioDelegate::Ptr delegate, int index) { if (index < 0 || index > m_folder->m_delegates.size()) { return false; @@ -230,7 +230,7 @@ bool ApplicationFolderModel::canAddDelegate(FolioDelegate *delegate, int index) return true; } -bool ApplicationFolderModel::addDelegate(FolioDelegate *delegate, int index) +bool ApplicationFolderModel::addDelegate(FolioDelegate::Ptr delegate, int index) { if (!canAddDelegate(delegate, index)) { return false; @@ -238,14 +238,14 @@ bool ApplicationFolderModel::addDelegate(FolioDelegate *delegate, int index) if (index == m_folder->m_delegates.size()) { beginInsertRows(QModelIndex(), index, index); - m_folder->m_delegates.append({delegate, 0, 0}); + m_folder->m_delegates.append({delegate, 0, 0, 0}); evaluateDelegateIndexes(false); endInsertRows(); } else if (m_folder->m_delegates[index].delegate->type() == FolioDelegate::None) { replaceGhostEntry(delegate); } else { beginInsertRows(QModelIndex(), index, index); - m_folder->m_delegates.insert(index, {delegate, 0, 0}); + m_folder->m_delegates.insert(index, {delegate, 0, 0, 0}); evaluateDelegateIndexes(false); endInsertRows(); } @@ -309,7 +309,7 @@ int ApplicationFolderModel::getGhostEntryPosition() void ApplicationFolderModel::setGhostEntry(int index) { - FolioDelegate *ghost = nullptr; + FolioDelegate::Ptr ghost = nullptr; // check if a ghost entry already exists for (int i = 0; i < m_folder->m_delegates.size(); i++) { @@ -328,14 +328,14 @@ void ApplicationFolderModel::setGhostEntry(int index) } if (!ghost) { - ghost = new FolioDelegate{m_folder->m_homeScreen}; + ghost = std::make_shared(m_folder->m_homeScreen); } // add empty delegate at new position addDelegate(ghost, index); } -void ApplicationFolderModel::replaceGhostEntry(FolioDelegate *delegate) +void ApplicationFolderModel::replaceGhostEntry(FolioDelegate::Ptr delegate) { for (int i = 0; i < m_folder->m_delegates.size(); i++) { if (m_folder->m_delegates[i].delegate->type() == FolioDelegate::None) { diff --git a/containments/homescreens/folio/folioapplicationfolder.h b/containments/homescreens/folio/folioapplicationfolder.h index a539b3f4..dd80b0b6 100644 --- a/containments/homescreens/folio/folioapplicationfolder.h +++ b/containments/homescreens/folio/folioapplicationfolder.h @@ -28,7 +28,7 @@ class FolioApplication; * @short Object that represents an application folder. */ -class FolioApplicationFolder : public QObject +class FolioApplicationFolder : public QObject, public std::enable_shared_from_this { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) @@ -36,9 +36,11 @@ class FolioApplicationFolder : public QObject Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset) public: + typedef std::shared_ptr Ptr; + FolioApplicationFolder(HomeScreen *parent = nullptr, QString name = QString{}); - static FolioApplicationFolder *fromJson(QJsonObject &obj, HomeScreen *parent); + static std::shared_ptr fromJson(QJsonObject &obj, HomeScreen *parent); QJsonObject toJson() const; QString name() const; @@ -47,10 +49,10 @@ public: QList appPreviews(); ApplicationFolderModel *applications(); - void setApplications(QList applications); + void setApplications(QList> applications); void moveEntry(int fromRow, int toRow); - bool addDelegate(FolioDelegate *delegate, int row); + bool addDelegate(std::shared_ptr delegate, int row); Q_INVOKABLE void removeDelegate(int row); int dropInsertPosition(int page, qreal x, qreal y); @@ -73,7 +75,7 @@ private: }; struct ApplicationDelegate { - FolioDelegate *delegate; + std::shared_ptr delegate; int columnIndex; int rowIndex; int pageIndex; @@ -91,16 +93,16 @@ public: rowIndexRole, pageIndexRole, }; - ApplicationFolderModel(FolioApplicationFolder *folder); + ApplicationFolderModel(FolioApplicationFolder *parent); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; - FolioDelegate *getDelegate(int index); + std::shared_ptr getDelegate(int index); void moveEntry(int fromRow, int toRow); - bool canAddDelegate(FolioDelegate *delegate, int index); - bool addDelegate(FolioDelegate *delegate, int index); + bool canAddDelegate(std::shared_ptr delegate, int index); + bool addDelegate(std::shared_ptr delegate, int index); void removeDelegate(int index); QPointF getDelegatePosition(int index); @@ -109,7 +111,7 @@ public: // invisible - existing delegate looks like it doesn't exist int getGhostEntryPosition(); void setGhostEntry(int index); - void replaceGhostEntry(FolioDelegate *delegate); + void replaceGhostEntry(std::shared_ptr delegate); void deleteGhostEntry(); // the index that dropping at the position given would place the delegate at. diff --git a/containments/homescreens/folio/foliodelegate.cpp b/containments/homescreens/folio/foliodelegate.cpp index 38973ad0..3b1d30d2 100644 --- a/containments/homescreens/folio/foliodelegate.cpp +++ b/containments/homescreens/folio/foliodelegate.cpp @@ -13,7 +13,7 @@ FolioDelegate::FolioDelegate(HomeScreen *parent) { } -FolioDelegate::FolioDelegate(FolioApplication *application, HomeScreen *parent) +FolioDelegate::FolioDelegate(FolioApplication::Ptr application, HomeScreen *parent) : QObject{parent} , m_type{FolioDelegate::Application} , m_application{application} @@ -22,7 +22,7 @@ FolioDelegate::FolioDelegate(FolioApplication *application, HomeScreen *parent) { } -FolioDelegate::FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent) +FolioDelegate::FolioDelegate(FolioApplicationFolder::Ptr folder, HomeScreen *parent) : QObject{parent} , m_type{FolioDelegate::Folder} , m_application{nullptr} @@ -31,7 +31,7 @@ FolioDelegate::FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent) { } -FolioDelegate::FolioDelegate(FolioWidget *widget, HomeScreen *parent) +FolioDelegate::FolioDelegate(FolioWidget::Ptr widget, HomeScreen *parent) : QObject{parent} , m_type{FolioDelegate::Widget} , m_application{nullptr} @@ -40,34 +40,34 @@ FolioDelegate::FolioDelegate(FolioWidget *widget, HomeScreen *parent) { } -FolioDelegate *FolioDelegate::fromJson(QJsonObject &obj, HomeScreen *parent) +FolioDelegate::Ptr FolioDelegate::fromJson(QJsonObject &obj, HomeScreen *parent) { const QString type = obj[QStringLiteral("type")].toString(); if (type == "application") { // read application - FolioApplication *app = FolioApplication::fromJson(obj, parent); + FolioApplication::Ptr app = FolioApplication::fromJson(obj, parent); if (app) { - return new FolioDelegate{app, parent}; + return std::make_shared(app, parent); } } else if (type == "folder") { // read folder - FolioApplicationFolder *folder = FolioApplicationFolder::fromJson(obj, parent); + FolioApplicationFolder::Ptr folder = FolioApplicationFolder::fromJson(obj, parent); if (folder) { - return new FolioDelegate{folder, parent}; + return std::make_shared(folder, parent); } } else if (type == "widget") { // read widget - FolioWidget *widget = FolioWidget::fromJson(obj, parent); + FolioWidget::Ptr widget = FolioWidget::fromJson(obj, parent); if (widget) { - return new FolioDelegate{widget, parent}; + return std::make_shared(widget, parent); } } else if (type == "none") { - return new FolioDelegate{parent}; + return std::make_shared(parent); } return nullptr; @@ -93,26 +93,41 @@ QJsonObject FolioDelegate::toJson() const return QJsonObject{}; } -FolioDelegate::Type FolioDelegate::type() +FolioDelegate::Type FolioDelegate::type() const { return m_type; } -FolioApplication *FolioDelegate::application() +FolioApplication::Ptr FolioDelegate::application() { return m_application; } -FolioApplicationFolder *FolioDelegate::folder() +FolioApplication *FolioDelegate::applicationRaw() +{ + return m_application.get(); +} + +FolioApplicationFolder::Ptr FolioDelegate::folder() { return m_folder; } -FolioWidget *FolioDelegate::widget() +FolioApplicationFolder *FolioDelegate::folderRaw() +{ + return m_folder.get(); +} + +FolioWidget::Ptr FolioDelegate::widget() { return m_widget; } +FolioWidget *FolioDelegate::widgetRaw() +{ + return m_widget.get(); +} + FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent) : FolioDelegate{parent} , m_homeScreen{parent} @@ -122,7 +137,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent) init(); } -FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication *application, HomeScreen *parent) +FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication::Ptr application, HomeScreen *parent) : FolioDelegate{application, parent} , m_homeScreen{parent} , m_row{row} @@ -131,7 +146,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication *appl init(); } -FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, HomeScreen *parent) +FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder::Ptr folder, HomeScreen *parent) : FolioDelegate{folder, parent} , m_homeScreen{parent} , m_row{row} @@ -140,7 +155,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder init(); } -FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget *widget, HomeScreen *parent) +FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget::Ptr widget, HomeScreen *parent) : FolioDelegate{widget, parent} , m_homeScreen{parent} , m_row{row} @@ -149,7 +164,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget *widget, H init(); } -FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate *delegate, HomeScreen *parent) +FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate::Ptr delegate, HomeScreen *parent) : FolioDelegate{parent} , m_homeScreen{parent} , m_row{row} @@ -207,21 +222,21 @@ void FolioPageDelegate::init() } if (m_widget) { - connect(m_widget, &FolioWidget::realTopLeftPositionChanged, this, [this](int rowOffset, int columnOffset) { + connect(m_widget.get(), &FolioWidget::realTopLeftPositionChanged, this, [this](int rowOffset, int columnOffset) { m_realRow += rowOffset; m_realColumn += columnOffset; }); } connect(homeScreenState, &HomeScreenState::pageOrientationChanged, this, [this]() { - setRowOnly(getTranslatedTopLeftRow(m_homeScreen, m_realRow, m_realColumn, this)); - setColumnOnly(getTranslatedTopLeftColumn(m_homeScreen, m_realRow, m_realColumn, this)); + setRowOnly(getTranslatedTopLeftRow(m_homeScreen, m_realRow, m_realColumn, this->shared_from_this())); + setColumnOnly(getTranslatedTopLeftColumn(m_homeScreen, m_realRow, m_realColumn, this->shared_from_this())); }); } -FolioPageDelegate *FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *parent) +FolioPageDelegate::Ptr FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *parent) { - FolioDelegate *fd = FolioDelegate::fromJson(obj, parent); + FolioDelegate::Ptr fd = FolioDelegate::fromJson(obj, parent); if (!fd) { return nullptr; @@ -233,13 +248,13 @@ FolioPageDelegate *FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *par int row = getTranslatedTopLeftRow(parent, realRow, realColumn, fd); int column = getTranslatedTopLeftColumn(parent, realRow, realColumn, fd); - FolioPageDelegate *delegate = new FolioPageDelegate{row, column, fd, parent}; + FolioPageDelegate::Ptr delegate = std::make_shared(row, column, fd, parent); fd->deleteLater(); return delegate; } -int FolioPageDelegate::getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd) +int FolioPageDelegate::getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate::Ptr fd) { int row = getTranslatedRow(homeScreen, realRow, realColumn); int column = getTranslatedColumn(homeScreen, realRow, realColumn); @@ -252,7 +267,7 @@ int FolioPageDelegate::getTranslatedTopLeftRow(HomeScreen *homeScreen, int realR } } -int FolioPageDelegate::getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd) +int FolioPageDelegate::getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate::Ptr fd) { int row = getTranslatedRow(homeScreen, realRow, realColumn); int column = getTranslatedColumn(homeScreen, realRow, realColumn); @@ -386,3 +401,8 @@ void FolioPageDelegate::setColumnOnly(int column) Q_EMIT columnChanged(); } } + +std::shared_ptr FolioPageDelegate::sharedPageDelegate() +{ + return static_pointer_cast(shared_from_this()); +} diff --git a/containments/homescreens/folio/foliodelegate.h b/containments/homescreens/folio/foliodelegate.h index 904f7e0d..359a2de6 100644 --- a/containments/homescreens/folio/foliodelegate.h +++ b/containments/homescreens/folio/foliodelegate.h @@ -15,15 +15,17 @@ class FolioApplication; class FolioApplicationFolder; class FolioWidget; -class FolioDelegate : public QObject +class FolioDelegate : public QObject, public std::enable_shared_from_this { Q_OBJECT Q_PROPERTY(FolioDelegate::Type type READ type CONSTANT) - Q_PROPERTY(FolioApplication *application READ application CONSTANT) - Q_PROPERTY(FolioApplicationFolder *folder READ folder CONSTANT) - Q_PROPERTY(FolioWidget *widget READ widget CONSTANT) + Q_PROPERTY(FolioApplication *application READ applicationRaw CONSTANT) + Q_PROPERTY(FolioApplicationFolder *folder READ folderRaw CONSTANT) + Q_PROPERTY(FolioWidget *widget READ widgetRaw CONSTANT) public: + typedef std::shared_ptr Ptr; + enum Type { None, Application, @@ -32,25 +34,31 @@ public: }; Q_ENUM(Type) - FolioDelegate(HomeScreen *parent = nullptr); - FolioDelegate(FolioApplication *application, HomeScreen *parent); - FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent); - FolioDelegate(FolioWidget *widget, HomeScreen *parent); + FolioDelegate(HomeScreen *parent); + FolioDelegate(std::shared_ptr application, HomeScreen *parent); + FolioDelegate(std::shared_ptr folder, HomeScreen *parent); + FolioDelegate(std::shared_ptr widget, HomeScreen *parent); - static FolioDelegate *fromJson(QJsonObject &obj, HomeScreen *parent); + static std::shared_ptr fromJson(QJsonObject &obj, HomeScreen *parent); virtual QJsonObject toJson() const; - FolioDelegate::Type type(); - FolioApplication *application(); - FolioApplicationFolder *folder(); - FolioWidget *widget(); + FolioDelegate::Type type() const; + + std::shared_ptr application(); + FolioApplication *applicationRaw(); + + std::shared_ptr folder(); + FolioApplicationFolder *folderRaw(); + + std::shared_ptr widget(); + FolioWidget *widgetRaw(); protected: FolioDelegate::Type m_type; - FolioApplication *m_application{nullptr}; - FolioApplicationFolder *m_folder{nullptr}; - FolioWidget *m_widget{nullptr}; + std::shared_ptr m_application{nullptr}; + std::shared_ptr m_folder{nullptr}; + std::shared_ptr m_widget{nullptr}; }; class FolioPageDelegate : public FolioDelegate @@ -61,15 +69,17 @@ class FolioPageDelegate : public FolioDelegate QML_UNCREATABLE("") public: - FolioPageDelegate(int row = 0, int column = 0, HomeScreen *parent = nullptr); - FolioPageDelegate(int row, int column, FolioApplication *application, HomeScreen *parent); - FolioPageDelegate(int row, int column, FolioApplicationFolder *folder, HomeScreen *parent); - FolioPageDelegate(int row, int column, FolioWidget *widget, HomeScreen *parent); - FolioPageDelegate(int row, int column, FolioDelegate *delegate, HomeScreen *parent); + typedef std::shared_ptr Ptr; - static FolioPageDelegate *fromJson(QJsonObject &obj, HomeScreen *parent); - static int getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd); - static int getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd); + FolioPageDelegate(int row = 0, int column = 0, HomeScreen *parent = nullptr); + FolioPageDelegate(int row, int column, std::shared_ptr application, HomeScreen *parent); + FolioPageDelegate(int row, int column, std::shared_ptr folder, HomeScreen *parent); + FolioPageDelegate(int row, int column, std::shared_ptr widget, HomeScreen *parent); + FolioPageDelegate(int row, int column, std::shared_ptr delegate, HomeScreen *parent); + + static std::shared_ptr fromJson(QJsonObject &obj, HomeScreen *parent); + static int getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, std::shared_ptr fd); + static int getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, std::shared_ptr fd); static int getTranslatedRow(HomeScreen *homeScreen, int realRow, int realColumn); static int getTranslatedColumn(HomeScreen *homeScreen, int realRow, int realColumn); @@ -81,6 +91,8 @@ public: int column(); void setColumn(int column); + std::shared_ptr sharedPageDelegate(); + Q_SIGNALS: void rowChanged(); void columnChanged(); diff --git a/containments/homescreens/folio/foliowidget.cpp b/containments/homescreens/folio/foliowidget.cpp index 9ba7ce3b..16bd2c1a 100644 --- a/containments/homescreens/folio/foliowidget.cpp +++ b/containments/homescreens/folio/foliowidget.cpp @@ -51,12 +51,12 @@ void FolioWidget::init() }); } -FolioWidget *FolioWidget::fromJson(QJsonObject &obj, HomeScreen *parent) +FolioWidget::Ptr FolioWidget::fromJson(QJsonObject &obj, HomeScreen *parent) { int id = obj[QStringLiteral("id")].toInt(); int gridWidth = obj[QStringLiteral("gridWidth")].toInt(); int gridHeight = obj[QStringLiteral("gridHeight")].toInt(); - return new FolioWidget(parent, id, gridWidth, gridHeight); + return std::make_shared(parent, id, gridWidth, gridHeight); } QJsonObject FolioWidget::toJson() const @@ -208,7 +208,7 @@ bool FolioWidget::isInBounds(int widgetRow, int widgetColumn, int row, int colum return (row >= widgetRow) && (row <= widgetRow + gridHeight() - 1) && (column >= widgetColumn) && (column <= widgetColumn + gridWidth() - 1); } -bool FolioWidget::overlapsWidget(int widgetRow, int widgetColumn, FolioWidget *otherWidget, int otherWidgetRow, int otherWidgetColumn) +bool FolioWidget::overlapsWidget(int widgetRow, int widgetColumn, FolioWidget::Ptr otherWidget, int otherWidgetRow, int otherWidgetColumn) { if (!otherWidget) { return false; diff --git a/containments/homescreens/folio/foliowidget.h b/containments/homescreens/folio/foliowidget.h index 34a6f2b6..36b27c51 100644 --- a/containments/homescreens/folio/foliowidget.h +++ b/containments/homescreens/folio/foliowidget.h @@ -22,7 +22,7 @@ public: /** * @short Object that represents a widget on the homescreen. */ -class FolioWidget : public QObject +class FolioWidget : public QObject, public std::enable_shared_from_this { Q_OBJECT Q_PROPERTY(int id READ id NOTIFY idChanged) @@ -32,10 +32,12 @@ class FolioWidget : public QObject Q_PROPERTY(PlasmaQuick::AppletQuickItem *visualApplet READ visualApplet NOTIFY visualAppletChanged) public: + typedef std::shared_ptr Ptr; + FolioWidget(HomeScreen *parent = nullptr, int id = -1, int gridWidth = 0, int gridHeight = 0); FolioWidget(HomeScreen *parent, Plasma::Applet *applet, int gridWidth, int gridHeight); - static FolioWidget *fromJson(QJsonObject &obj, HomeScreen *parent); + static std::shared_ptr fromJson(QJsonObject &obj, HomeScreen *parent); QJsonObject toJson() const; int id() const; @@ -59,7 +61,7 @@ public: // query whether (row, column) is inside this widget, if it was at position (widgetRow, widgetColumn) bool isInBounds(int widgetRow, int widgetColumn, int row, int column); - bool overlapsWidget(int widgetRow, int widgetColumn, FolioWidget *otherWidget, int otherWidgetRow, int otherWidgetColumn); + bool overlapsWidget(int widgetRow, int widgetColumn, std::shared_ptr otherWidget, int otherWidgetRow, int otherWidgetColumn); Plasma::Applet *applet() const; void setApplet(Plasma::Applet *applet); diff --git a/containments/homescreens/folio/homescreenstate.cpp b/containments/homescreens/folio/homescreenstate.cpp index cdac52ce..ab84c058 100644 --- a/containments/homescreens/folio/homescreenstate.cpp +++ b/containments/homescreens/folio/homescreenstate.cpp @@ -517,12 +517,17 @@ void HomeScreenState::setFolderOpenProgress(qreal folderOpenProgress) } } -FolioApplicationFolder *HomeScreenState::currentFolder() const +FolioApplicationFolder::Ptr HomeScreenState::currentFolder() const { return m_currentFolder; } -void HomeScreenState::setCurrentFolder(FolioApplicationFolder *folder) +FolioApplicationFolder *HomeScreenState::currentFolderRaw() const +{ + return m_currentFolder.get(); +} + +void HomeScreenState::setCurrentFolder(FolioApplicationFolder::Ptr folder) { if (m_currentFolder != folder) { m_currentFolder = folder; @@ -662,17 +667,17 @@ FolioDelegate *HomeScreenState::getPageDelegateAt(int page, int row, int column) return nullptr; } - FolioDelegate *delegate = pageModel->getDelegate(row, column); + FolioDelegate::Ptr delegate = pageModel->getDelegate(row, column); if (!delegate) { return nullptr; } - return delegate; + return delegate.get(); } FolioDelegate *HomeScreenState::getFavouritesDelegateAt(int position) { - return m_homeScreen->favouritesModel()->getEntryAt(position); + return m_homeScreen->favouritesModel()->getEntryAt(position).get(); } FolioDelegate *HomeScreenState::getFolderDelegateAt(int position) @@ -681,7 +686,7 @@ FolioDelegate *HomeScreenState::getFolderDelegateAt(int position) return nullptr; } - return m_currentFolder->applications()->getDelegate(position); + return m_currentFolder->applications()->getDelegate(position).get(); } QPointF HomeScreenState::getPageDelegateScreenPosition(int page, int row, int column) @@ -799,7 +804,7 @@ void HomeScreenState::goToFolderPage(int page, bool snap) void HomeScreenState::openFolder(qreal delegateX, qreal delegateY, FolioApplicationFolder *folder) { - setCurrentFolder(folder); + setCurrentFolder(folder->shared_from_this()); m_openFolderAnim->stop(); m_closeFolderAnim->stop(); diff --git a/containments/homescreens/folio/homescreenstate.h b/containments/homescreens/folio/homescreenstate.h index 28b5d3e5..9614ba8c 100644 --- a/containments/homescreens/folio/homescreenstate.h +++ b/containments/homescreens/folio/homescreenstate.h @@ -60,7 +60,7 @@ class HomeScreenState : public QObject Q_PROPERTY(qreal folderPageContentWidth READ folderPageContentWidth WRITE setFolderPageContentWidth NOTIFY folderPageContentWidthChanged) Q_PROPERTY(qreal folderPageContentHeight READ folderPageContentHeight WRITE setFolderPageContentHeight NOTIFY folderPageContentHeightChanged) Q_PROPERTY(qreal folderOpenProgress READ folderOpenProgress WRITE setFolderOpenProgress NOTIFY folderOpenProgressChanged) - Q_PROPERTY(FolioApplicationFolder *currentFolder READ currentFolder NOTIFY currentFolderChanged) + Q_PROPERTY(FolioApplicationFolder *currentFolder READ currentFolderRaw NOTIFY currentFolderChanged) Q_PROPERTY(qreal folderGridLength READ folderGridLength NOTIFY folderGridLengthChanged) Q_PROPERTY(qreal settingsOpenProgress READ settingsOpenProgress WRITE setSettingsOpenProgress NOTIFY settingsOpenProgressChanged) @@ -208,8 +208,9 @@ public: int folderGridLength() const; void calculateFolderGridLength(); - FolioApplicationFolder *currentFolder() const; - void setCurrentFolder(FolioApplicationFolder *folder); + std::shared_ptr currentFolder() const; + FolioApplicationFolder *currentFolderRaw() const; + void setCurrentFolder(std::shared_ptr folder); // the progress for the opening of the settings view qreal settingsOpenProgress(); @@ -389,7 +390,7 @@ private: qreal m_folderPageContentWidth{0}; qreal m_folderPageContentHeight{0}; qreal m_folderOpenProgress{0}; - FolioApplicationFolder *m_currentFolder{nullptr}; + std::shared_ptr m_currentFolder{nullptr}; int m_folderGridLength{0}; qreal m_settingsOpenProgress{0}; diff --git a/containments/homescreens/folio/pagemodel.cpp b/containments/homescreens/folio/pagemodel.cpp index 744a57af..0abe3438 100644 --- a/containments/homescreens/folio/pagemodel.cpp +++ b/containments/homescreens/folio/pagemodel.cpp @@ -6,7 +6,7 @@ #include "homescreenstate.h" #include "widgetsmanager.h" -PageModel::PageModel(QList delegates, QObject *parent, HomeScreen *homeScreen) +PageModel::PageModel(QList delegates, QObject *parent, HomeScreen *homeScreen) : QAbstractListModel{parent} , m_homeScreen{homeScreen} , m_delegates{delegates} @@ -15,7 +15,7 @@ PageModel::PageModel(QList delegates, QObject *parent, Home if (applet) { // delete any instance of this widget for (int i = 0; i < m_delegates.size(); i++) { - auto *delegate = m_delegates[i]; + FolioPageDelegate::Ptr delegate = m_delegates[i]; if (delegate->type() == FolioDelegate::Widget && delegate->widget()->applet() == applet) { removeDelegate(i); break; @@ -29,12 +29,12 @@ PageModel::~PageModel() = default; PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen) { - QList delegates; + QList delegates; for (QJsonValueRef r : arr) { QJsonObject obj = r.toObject(); - FolioPageDelegate *delegate = FolioPageDelegate::fromJson(obj, homeScreen); + FolioPageDelegate::Ptr delegate = FolioPageDelegate::fromJson(obj, homeScreen); if (delegate) { delegates.append(delegate); } @@ -43,7 +43,7 @@ PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *hom PageModel *model = new PageModel{delegates, parent, homeScreen}; // ensure delegates can request saves - for (auto *delegate : delegates) { + for (FolioPageDelegate::Ptr delegate : delegates) { model->connectSaveRequests(delegate); } @@ -54,7 +54,7 @@ QJsonArray PageModel::toJson() const { QJsonArray arr; - for (FolioPageDelegate *delegate : m_delegates) { + for (FolioPageDelegate::Ptr delegate : m_delegates) { if (!delegate) { continue; } @@ -79,7 +79,7 @@ QVariant PageModel::data(const QModelIndex &index, int role) const switch (role) { case DelegateRole: - return QVariant::fromValue(m_delegates.at(index.row())); + return QVariant::fromValue(m_delegates.at(index.row()).get()); } return QVariant(); @@ -136,7 +136,7 @@ bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate) } // check if any delegate exists at any of the spots where the widget is being added - for (FolioPageDelegate *d : m_delegates) { + for (FolioPageDelegate::Ptr d : m_delegates) { if (delegate->widget()->isInBounds(row, column, d->row(), d->column())) { return false; } else if (d->type() == FolioDelegate::Widget) { @@ -151,7 +151,7 @@ bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate) // inserting app or folder... // check if there already exists a delegate in this space - for (FolioPageDelegate *d : m_delegates) { + for (FolioPageDelegate::Ptr d : m_delegates) { if (d->row() == row && d->column() == column) { return false; } else if (d->type() == FolioDelegate::Widget && d->widget()->isInBounds(d->row(), d->column(), row, column)) { @@ -163,9 +163,9 @@ bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate) return true; } -bool PageModel::addDelegate(FolioPageDelegate *delegate) +bool PageModel::addDelegate(FolioPageDelegate::Ptr delegate) { - if (!canAddDelegate(delegate->row(), delegate->column(), delegate)) { + if (!canAddDelegate(delegate->row(), delegate->column(), delegate.get())) { return false; } @@ -180,9 +180,9 @@ bool PageModel::addDelegate(FolioPageDelegate *delegate) return true; } -FolioPageDelegate *PageModel::getDelegate(int row, int col) +FolioPageDelegate::Ptr PageModel::getDelegate(int row, int col) { - for (FolioPageDelegate *d : m_delegates) { + for (FolioPageDelegate::Ptr d : m_delegates) { if (d->row() == row && d->column() == col) { return d; } @@ -207,23 +207,21 @@ void PageModel::moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int new return; } - // test if we can add the delegate with new size and position - FolioWidget *testWidget = new FolioWidget(m_homeScreen, 0, 0, 0); - // we have to use setGridWidth and setGridHeight since it takes into account the page orientation + // Test if we can add the delegate with new size and position + FolioWidget::Ptr testWidget = std::make_shared(m_homeScreen, 0, 0, 0); + // We have to use setGridWidth and setGridHeight since it takes into account the page orientation testWidget->setGridWidth(newGridWidth); testWidget->setGridHeight(newGridHeight); - FolioDelegate *testDelegate = new FolioDelegate(testWidget, m_homeScreen); + FolioDelegate::Ptr testDelegate = std::make_shared(testWidget, m_homeScreen); + + // testWidget and testDelegate will get cleaned up automatically since are smart pointers // NOT THREAD SAFE! // which is fine, because the GUI isn't multithreaded - int index = m_delegates.indexOf(delegate); + int index = m_delegates.indexOf(delegate->sharedPageDelegate()); m_delegates.remove(index); // remove the delegate temporarily, since we don't want it to check overlapping of itself - bool canAdd = canAddDelegate(newRow, newColumn, testDelegate); - m_delegates.insert(index, delegate); // add it back - - // cleanup test delegate - testDelegate->deleteLater(); - testWidget->deleteLater(); + bool canAdd = canAddDelegate(newRow, newColumn, testDelegate.get()); + m_delegates.insert(index, delegate->sharedPageDelegate()); // add it back if (!canAdd) { return; @@ -240,12 +238,12 @@ bool PageModel::isPageEmpty() return m_delegates.size() == 0; } -void PageModel::connectSaveRequests(FolioDelegate *delegate) +void PageModel::connectSaveRequests(FolioDelegate::Ptr delegate) { if (delegate->type() == FolioDelegate::Folder && delegate->folder()) { - connect(delegate->folder(), &FolioApplicationFolder::saveRequested, this, &PageModel::save); + connect(delegate->folder().get(), &FolioApplicationFolder::saveRequested, this, &PageModel::save); } else if (delegate->type() == FolioDelegate::Widget && delegate->widget()) { - connect(delegate->widget(), &FolioWidget::saveRequested, this, &PageModel::save); + connect(delegate->widget().get(), &FolioWidget::saveRequested, this, &PageModel::save); } } diff --git a/containments/homescreens/folio/pagemodel.h b/containments/homescreens/folio/pagemodel.h index b0e6657e..1b9ce6a6 100644 --- a/containments/homescreens/folio/pagemodel.h +++ b/containments/homescreens/folio/pagemodel.h @@ -29,7 +29,9 @@ public: ShownRole, }; - PageModel(QList delegates = QList{}, QObject *parent = nullptr, HomeScreen *m_homeScreen = nullptr); + PageModel(QList> delegates = QList>{}, + QObject *parent = nullptr, + HomeScreen *m_homeScreen = nullptr); ~PageModel(); static PageModel *fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen); @@ -43,8 +45,8 @@ public: Q_INVOKABLE void removeDelegate(int row, int col); Q_INVOKABLE void removeDelegate(int index); Q_INVOKABLE bool canAddDelegate(int row, int column, FolioDelegate *delegate); - bool addDelegate(FolioPageDelegate *delegate); - FolioPageDelegate *getDelegate(int row, int col); + bool addDelegate(std::shared_ptr delegate); + std::shared_ptr getDelegate(int row, int col); Q_INVOKABLE void moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int newRow, int newColumn, int newGridWidth, int newGridHeight); @@ -57,8 +59,8 @@ Q_SIGNALS: void saveRequested(); private: - void connectSaveRequests(FolioDelegate *delegate); + void connectSaveRequests(std::shared_ptr delegate); HomeScreen *m_homeScreen{nullptr}; - QList m_delegates; + QList> m_delegates; };