folio: Use smart pointers to manage delegate lifetimes

Currently delegates do not get deleted when removed from models. Due to
the complexity of drag state and other objects, we can't simply delete
the delegate when removed from the model because they might still be
involved in animations or other state at the time of removal. Use smart
pointers to have the delegate objects deleted instead.

QML unfortunately doesn't support QSharedPointer, so we need to expose raw pointers to it.
This commit is contained in:
Devin Lin 2025-02-21 18:06:24 +00:00
parent c8d215f2a3
commit 3550caa580
18 changed files with 250 additions and 193 deletions

View file

@ -80,17 +80,17 @@ void ApplicationListModel::load()
m_delegates.clear(); m_delegates.clear();
QList<FolioDelegate *> unorderedList; QList<FolioDelegate::Ptr> unorderedList;
const KService::List apps = KApplicationTrader::query(filter); const KService::List apps = KApplicationTrader::query(filter);
for (const KService::Ptr &service : apps) { for (const KService::Ptr &service : apps) {
FolioApplication *app = new FolioApplication{m_homeScreen, service}; FolioApplication::Ptr app = std::make_shared<FolioApplication>(m_homeScreen, service);
FolioDelegate *delegate = new FolioDelegate{app, m_homeScreen}; FolioDelegate::Ptr delegate = std::make_shared<FolioDelegate>(app, m_homeScreen);
unorderedList << delegate; 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; 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(); return QVariant();
} }
FolioDelegate *delegate = m_delegates.at(index.row()); FolioDelegate::Ptr delegate = m_delegates.at(index.row());
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
case DelegateRole: case DelegateRole:
return QVariant::fromValue(delegate); return QVariant::fromValue(delegate.get());
case NameRole: case NameRole:
if (!delegate->application()) { if (!delegate->application()) {
return QVariant(); return QVariant();

View file

@ -43,8 +43,8 @@ public Q_SLOTS:
protected: protected:
HomeScreen *m_homeScreen{nullptr}; HomeScreen *m_homeScreen{nullptr};
QList<FolioDelegate *> m_delegates;
QList<std::shared_ptr<FolioDelegate>> m_delegates;
QTimer *m_reloadAppsTimer{nullptr}; QTimer *m_reloadAppsTimer{nullptr};
}; };

View file

@ -109,12 +109,17 @@ void DelegateDragPosition::setFolderPosition(int folderPosition)
} }
} }
FolioApplicationFolder *DelegateDragPosition::folder() const FolioApplicationFolder::Ptr DelegateDragPosition::folder() const
{ {
return m_folder; 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) { if (m_folder != folder) {
m_folder = folder; m_folder = folder;
@ -197,12 +202,17 @@ DelegateDragPosition *DragState::startPosition() const
return m_startPosition; return m_startPosition;
} }
FolioDelegate *DragState::dropDelegate() const FolioDelegate::Ptr DragState::dropDelegate() const
{ {
return m_dropDelegate; 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; m_dropDelegate = dropDelegate;
Q_EMIT dropDelegateChanged(); Q_EMIT dropDelegateChanged();
@ -266,7 +276,7 @@ void DragState::onDelegateDragPositionOverFolderViewChanged()
qreal x = getPointerX(); qreal x = getPointerX();
qreal y = getPointerY(); qreal y = getPointerY();
auto *folder = m_state->currentFolder(); FolioApplicationFolder::Ptr folder = m_state->currentFolder();
if (!folder) { if (!folder) {
return; return;
} }
@ -370,7 +380,7 @@ void DragState::onDelegateDragPositionOverFavouritesChanged()
// start folder open timer if hovering over a folder // start folder open timer if hovering over a folder
// get delegate being hovered over // 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 // 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) { 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); PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page);
if (pageModel) { if (pageModel) {
// get delegate being hovered over // 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 // 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) { 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 // fetch delegate at start position
if (KService::Ptr service = KService::serviceByStorageId(storageId)) { if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
FolioApplication *app = new FolioApplication{m_homeScreen, service}; FolioApplication::Ptr app = std::make_shared<FolioApplication>(m_homeScreen, service);
setDropDelegate(new FolioDelegate{app, m_homeScreen}); setDropDelegate(std::make_shared<FolioDelegate>(app, m_homeScreen));
} else { } else {
setDropDelegate(nullptr); setDropDelegate(nullptr);
} }
@ -511,7 +521,7 @@ void DragState::onDelegateDragFromFolderStarted(FolioApplicationFolder *folder,
setDropDelegate(folder->applications()->getDelegate(position)); setDropDelegate(folder->applications()->getDelegate(position));
// set start location // set start location
m_startPosition->setFolder(folder); m_startPosition->setFolder(folder->shared_from_this());
m_startPosition->setFolderPosition(position); m_startPosition->setFolderPosition(position);
m_startPosition->setLocation(DelegateDragPosition::Folder); m_startPosition->setLocation(DelegateDragPosition::Folder);
} }
@ -520,8 +530,8 @@ void DragState::onDelegateDragFromWidgetListStarted(QString appletPluginId)
{ {
// default widget has dimensions of 1x1, and id of -1 // default widget has dimensions of 1x1, and id of -1
m_createdAppletPluginId = appletPluginId; m_createdAppletPluginId = appletPluginId;
FolioWidget *widget = new FolioWidget{m_homeScreen, -1, 1, 1}; FolioWidget::Ptr widget = std::make_shared<FolioWidget>(m_homeScreen, -1, 1, 1);
setDropDelegate(new FolioDelegate{widget, m_homeScreen}); setDropDelegate(std::make_shared<FolioDelegate>(widget, m_homeScreen));
// set start location // set start location
m_startPosition->setLocation(DelegateDragPosition::WidgetList); m_startPosition->setLocation(DelegateDragPosition::WidgetList);
@ -619,7 +629,7 @@ void DragState::onOpenFolderTimerFinished()
return; return;
} }
FolioApplicationFolder *folder = nullptr; FolioApplicationFolder::Ptr folder = nullptr;
QPointF screenPosition; QPointF screenPosition;
switch (m_candidateDropPosition->location()) { switch (m_candidateDropPosition->location()) {
@ -631,7 +641,7 @@ void DragState::onOpenFolderTimerFinished()
} }
// get delegate being hovered over // 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) { if (!delegate || delegate->type() != FolioDelegate::Folder) {
return; return;
} }
@ -643,7 +653,7 @@ void DragState::onOpenFolderTimerFinished()
} }
case DelegateDragPosition::Favourites: { case DelegateDragPosition::Favourites: {
// get delegate being hovered over in favourites bar // 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) { if (!delegate || delegate->type() != FolioDelegate::Folder) {
return; return;
} }
@ -657,7 +667,7 @@ void DragState::onOpenFolderTimerFinished()
} }
// open the folder // open the folder
m_state->openFolder(screenPosition.x(), screenPosition.y(), folder); m_state->openFolder(screenPosition.x(), screenPosition.y(), folder.get());
} }
void DragState::onLeaveFolderTimerFinished() void DragState::onLeaveFolderTimerFinished()
@ -678,7 +688,7 @@ void DragState::onChangeFolderPageTimerFinished()
return; return;
} }
auto *folder = m_state->currentFolder(); FolioApplicationFolder::Ptr folder = m_state->currentFolder();
qreal x = getPointerX(); qreal x = getPointerX();
qreal y = getPointerY(); qreal y = getPointerY();
@ -714,7 +724,7 @@ void DragState::onFolderInsertBetweenTimerFinished()
return; return;
} }
auto *folder = m_state->currentFolder(); FolioApplicationFolder::Ptr folder = m_state->currentFolder();
// update the candidate drop position // update the candidate drop position
m_candidateDropPosition->setFolder(folder); m_candidateDropPosition->setFolder(folder);
@ -782,10 +792,10 @@ bool DragState::createDropPositionDelegate()
int column = m_candidateDropPosition->pageColumn(); int column = m_candidateDropPosition->pageColumn();
// delegate to add // delegate to add
FolioPageDelegate *delegate = new FolioPageDelegate{row, column, m_dropDelegate, m_homeScreen}; FolioPageDelegate::Ptr delegate = std::make_shared<FolioPageDelegate>(row, column, m_dropDelegate, m_homeScreen);
// delegate that exists at the drop position // 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 a delegate already exists at the spot, check if we can insert/create a folder
if (existingDelegate) { if (existingDelegate) {
@ -801,10 +811,10 @@ bool DragState::createDropPositionDelegate()
} else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) { } else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) {
// create a folder from the two apps // create a folder from the two apps
FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME); FolioApplicationFolder::Ptr folder = std::make_shared<FolioApplicationFolder>(m_homeScreen, DEFAULT_FOLDER_NAME);
folder->addDelegate(delegate, 0); folder->addDelegate(delegate, 0);
folder->addDelegate(existingDelegate, 0); folder->addDelegate(existingDelegate, 0);
FolioPageDelegate *folderDelegate = new FolioPageDelegate{row, column, folder, m_homeScreen}; FolioPageDelegate::Ptr folderDelegate = std::make_shared<FolioPageDelegate>(row, column, folder, m_homeScreen);
page->removeDelegate(row, column); page->removeDelegate(row, column);
page->addDelegate(folderDelegate); page->addDelegate(folderDelegate);
@ -828,7 +838,7 @@ bool DragState::createDropPositionDelegate()
} }
case DelegateDragPosition::Favourites: { case DelegateDragPosition::Favourites: {
// delegate that exists at the drop position // 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 a delegate already exists at the spot, check if we can insert/create a folder
if (existingDelegate) { if (existingDelegate) {
@ -844,10 +854,10 @@ bool DragState::createDropPositionDelegate()
} else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) { } else if (existingDelegate->type() == FolioDelegate::Application && !isStartPositionEqualDropPosition()) {
// create a folder from the two apps // create a folder from the two apps
FolioApplicationFolder *folder = new FolioApplicationFolder(m_homeScreen, DEFAULT_FOLDER_NAME); FolioApplicationFolder::Ptr folder = std::make_shared<FolioApplicationFolder>(m_homeScreen, DEFAULT_FOLDER_NAME);
folder->addDelegate(m_dropDelegate, 0); folder->addDelegate(m_dropDelegate, 0);
folder->addDelegate(existingDelegate, 0); folder->addDelegate(existingDelegate, 0);
FolioDelegate *folderDelegate = new FolioDelegate{folder, m_homeScreen}; FolioDelegate::Ptr folderDelegate = std::make_shared<FolioDelegate>(folder, m_homeScreen);
m_homeScreen->favouritesModel()->removeEntry(m_candidateDropPosition->favouritesPosition()); m_homeScreen->favouritesModel()->removeEntry(m_candidateDropPosition->favouritesPosition());
m_homeScreen->favouritesModel()->addEntry(m_candidateDropPosition->favouritesPosition(), folderDelegate); m_homeScreen->favouritesModel()->addEntry(m_candidateDropPosition->favouritesPosition(), folderDelegate);
@ -878,7 +888,7 @@ bool DragState::createDropPositionDelegate()
break; break;
} }
case DelegateDragPosition::Folder: { case DelegateDragPosition::Folder: {
auto *folder = m_candidateDropPosition->folder(); FolioApplicationFolder::Ptr folder = m_candidateDropPosition->folder();
if (!folder) { if (!folder) {
break; break;
} }

View file

@ -23,7 +23,7 @@ class DelegateDragPosition : public QObject
Q_PROPERTY(int pageColumn READ pageColumn NOTIFY pageColumnChanged) Q_PROPERTY(int pageColumn READ pageColumn NOTIFY pageColumnChanged)
Q_PROPERTY(int favouritesPosition READ favouritesPosition NOTIFY favouritesPositionChanged) Q_PROPERTY(int favouritesPosition READ favouritesPosition NOTIFY favouritesPositionChanged)
Q_PROPERTY(int folderPosition READ folderPosition NOTIFY folderPositionChanged) 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: public:
enum Location { Pages, Favourites, AppDrawer, Folder, WidgetList }; enum Location { Pages, Favourites, AppDrawer, Folder, WidgetList };
@ -53,8 +53,9 @@ public:
void setFolderPosition(int folderPosition); void setFolderPosition(int folderPosition);
// TODO: what if the folder becomes invalid? we need to clear it // TODO: what if the folder becomes invalid? we need to clear it
FolioApplicationFolder *folder() const; std::shared_ptr<FolioApplicationFolder> folder() const;
void setFolder(FolioApplicationFolder *folder); FolioApplicationFolder *folderRaw() const;
void setFolder(std::shared_ptr<FolioApplicationFolder> folder);
Q_SIGNALS: Q_SIGNALS:
void locationChanged(); void locationChanged();
@ -72,7 +73,7 @@ private:
int m_pageColumn{0}; int m_pageColumn{0};
int m_favouritesPosition{0}; int m_favouritesPosition{0};
int m_folderPosition{0}; int m_folderPosition{0};
FolioApplicationFolder *m_folder{nullptr}; std::shared_ptr<FolioApplicationFolder> m_folder{nullptr};
}; };
Q_DECLARE_METATYPE(DelegateDragPosition); Q_DECLARE_METATYPE(DelegateDragPosition);
@ -82,15 +83,17 @@ class DragState : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(DelegateDragPosition *candidateDropPosition READ candidateDropPosition CONSTANT) Q_PROPERTY(DelegateDragPosition *candidateDropPosition READ candidateDropPosition CONSTANT)
Q_PROPERTY(DelegateDragPosition *startPosition READ startPosition 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: public:
DragState(HomeScreenState *state = nullptr, HomeScreen *parent = nullptr); DragState(HomeScreenState *state = nullptr, HomeScreen *parent = nullptr);
DelegateDragPosition *candidateDropPosition() const; DelegateDragPosition *candidateDropPosition() const;
DelegateDragPosition *startPosition() const; DelegateDragPosition *startPosition() const;
FolioDelegate *dropDelegate() const;
void setDropDelegate(FolioDelegate *dropDelegate); std::shared_ptr<FolioDelegate> dropDelegate() const;
FolioDelegate *dropDelegateRaw() const;
void setDropDelegate(std::shared_ptr<FolioDelegate> dropDelegate);
Q_SIGNALS: Q_SIGNALS:
void dropDelegateChanged(); void dropDelegateChanged();
@ -157,7 +160,7 @@ private:
int m_favouritesInsertBetweenIndex{0}; int m_favouritesInsertBetweenIndex{0};
// the delegate that is being dropped // the delegate that is being dropped
FolioDelegate *m_dropDelegate{nullptr}; std::shared_ptr<FolioDelegate> m_dropDelegate{nullptr};
// where we are hovering over, potentially to drop the delegate // where we are hovering over, potentially to drop the delegate
DelegateDragPosition *const m_candidateDropPosition{nullptr}; DelegateDragPosition *const m_candidateDropPosition{nullptr};

View file

@ -40,7 +40,7 @@ QVariant FavouritesModel::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case DelegateRole: case DelegateRole:
return QVariant::fromValue(m_delegates.at(index.row()).delegate); return QVariant::fromValue(m_delegates.at(index.row()).delegate.get());
} }
return QVariant(); return QVariant();
@ -90,7 +90,7 @@ void FavouritesModel::moveEntry(int fromRow, int toRow)
save(); save();
} }
bool FavouritesModel::canAddEntry(int row, FolioDelegate *delegate) bool FavouritesModel::canAddEntry(int row, FolioDelegate::Ptr delegate)
{ {
if (!delegate) { if (!delegate) {
return false; return false;
@ -103,7 +103,7 @@ bool FavouritesModel::canAddEntry(int row, FolioDelegate *delegate)
return true; return true;
} }
bool FavouritesModel::addEntry(int row, FolioDelegate *delegate) bool FavouritesModel::addEntry(int row, FolioDelegate::Ptr delegate)
{ {
if (!canAddEntry(row, delegate)) { if (!canAddEntry(row, delegate)) {
return false; return false;
@ -129,7 +129,7 @@ bool FavouritesModel::addEntry(int row, FolioDelegate *delegate)
return true; return true;
} }
FolioDelegate *FavouritesModel::getEntryAt(int row) FolioDelegate::Ptr FavouritesModel::getEntryAt(int row)
{ {
if (row < 0 || row >= m_delegates.size()) { if (row < 0 || row >= m_delegates.size()) {
return nullptr; return nullptr;
@ -186,12 +186,12 @@ void FavouritesModel::setGhostEntry(int row)
// if it doesn't, add a new empty delegate // if it doesn't, add a new empty delegate
if (!found) { if (!found) {
FolioDelegate *ghost = new FolioDelegate{m_homeScreen}; FolioDelegate::Ptr ghost = std::make_shared<FolioDelegate>(m_homeScreen);
addEntry(row, ghost); addEntry(row, ghost);
} }
} }
void FavouritesModel::replaceGhostEntry(FolioDelegate *delegate) void FavouritesModel::replaceGhostEntry(FolioDelegate::Ptr delegate)
{ {
for (int i = 0; i < m_delegates.size(); i++) { for (int i = 0; i < m_delegates.size(); i++) {
if (m_delegates[i].delegate->type() == FolioDelegate::None) { if (m_delegates[i].delegate->type() == FolioDelegate::None) {
@ -221,7 +221,7 @@ QJsonArray FavouritesModel::exportToJson()
{ {
QJsonArray arr; QJsonArray arr;
for (int i = 0; i < m_delegates.size(); i++) { 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 this delegate is empty, ignore it
if (!delegate || delegate->type() == FolioDelegate::None) { if (!delegate || delegate->type() == FolioDelegate::None) {
@ -264,7 +264,7 @@ void FavouritesModel::loadFromJson(QJsonArray arr)
for (QJsonValueRef r : arr) { for (QJsonValueRef r : arr) {
QJsonObject obj = r.toObject(); QJsonObject obj = r.toObject();
FolioDelegate *delegate = FolioDelegate::fromJson(obj, m_homeScreen); FolioDelegate::Ptr delegate = FolioDelegate::fromJson(obj, m_homeScreen);
if (delegate) { if (delegate) {
connectSaveRequests(delegate); connectSaveRequests(delegate);
@ -275,10 +275,10 @@ void FavouritesModel::loadFromJson(QJsonArray arr)
endResetModel(); endResetModel();
} }
void FavouritesModel::connectSaveRequests(FolioDelegate *delegate) void FavouritesModel::connectSaveRequests(FolioDelegate::Ptr delegate)
{ {
if (delegate->type() == FolioDelegate::Folder && delegate->folder()) { if (delegate->type() == FolioDelegate::Folder && delegate->folder()) {
connect(delegate->folder(), &FolioApplicationFolder::saveRequested, this, &FavouritesModel::save); connect(delegate->folder().get(), &FolioApplicationFolder::saveRequested, this, &FavouritesModel::save);
} }
} }

View file

@ -20,7 +20,7 @@ class HomeScreen;
class FolioDelegate; class FolioDelegate;
struct FavouritesDelegate { struct FavouritesDelegate {
FolioDelegate *delegate; std::shared_ptr<FolioDelegate> delegate;
qreal xPosition; qreal xPosition;
}; };
@ -41,9 +41,9 @@ public:
Q_INVOKABLE void removeEntry(int row); Q_INVOKABLE void removeEntry(int row);
void moveEntry(int fromRow, int toRow); void moveEntry(int fromRow, int toRow);
bool canAddEntry(int row, FolioDelegate *delegate); bool canAddEntry(int row, std::shared_ptr<FolioDelegate> delegate);
bool addEntry(int row, FolioDelegate *delegate); bool addEntry(int row, std::shared_ptr<FolioDelegate> delegate);
FolioDelegate *getEntryAt(int row); std::shared_ptr<FolioDelegate> getEntryAt(int row);
// whether the dock is full, we can't add any more items // whether the dock is full, we can't add any more items
bool isFull() const; bool isFull() const;
@ -53,7 +53,7 @@ public:
// invisible - existing delegate looks like it doesn't exist // invisible - existing delegate looks like it doesn't exist
int getGhostEntryPosition(); int getGhostEntryPosition();
void setGhostEntry(int row); void setGhostEntry(int row);
void replaceGhostEntry(FolioDelegate *delegate); void replaceGhostEntry(std::shared_ptr<FolioDelegate> delegate);
void deleteGhostEntry(); void deleteGhostEntry();
// whether the position given is in between 2 delegates, or at the edge. // whether the position given is in between 2 delegates, or at the edge.
@ -71,7 +71,7 @@ public:
void loadFromJson(QJsonArray arr); void loadFromJson(QJsonArray arr);
private: private:
void connectSaveRequests(FolioDelegate *delegate); void connectSaveRequests(std::shared_ptr<FolioDelegate> delegate);
// get the x (or y) position where delegates start being placed // get the x (or y) position where delegates start being placed
qreal getDelegateRowStartPos() const; qreal getDelegateRowStartPos() const;

View file

@ -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(); QString storageId = obj[QStringLiteral("storageId")].toString();
if (KService::Ptr service = KService::serviceByStorageId(storageId)) { if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
return new FolioApplication(parent, service); return std::make_shared<FolioApplication>(parent, service);
} }
return nullptr; return nullptr;
} }

View file

@ -23,7 +23,7 @@ class HomeScreen;
/** /**
* @short Object that represents an application. * @short Object that represents an application.
*/ */
class FolioApplication : public QObject class FolioApplication : public QObject, public std::enable_shared_from_this<FolioApplication>
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool running READ running NOTIFY windowChanged) Q_PROPERTY(bool running READ running NOTIFY windowChanged)
@ -32,9 +32,11 @@ class FolioApplication : public QObject
Q_PROPERTY(QString storageId READ storageId NOTIFY storageIdChanged) Q_PROPERTY(QString storageId READ storageId NOTIFY storageIdChanged)
public: public:
typedef std::shared_ptr<FolioApplication> Ptr;
FolioApplication(HomeScreen *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer<KService>{nullptr}); FolioApplication(HomeScreen *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer<KService>{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; QJsonObject toJson() const;
bool running() const; bool running() const;

View file

@ -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(); QString name = obj[QStringLiteral("name")].toString();
QList<FolioApplication *> apps; QList<FolioApplication::Ptr> apps;
for (auto storageId : obj[QStringLiteral("apps")].toArray()) { for (auto storageId : obj[QStringLiteral("apps")].toArray()) {
if (KService::Ptr service = KService::serviceByStorageId(storageId.toString())) { if (KService::Ptr service = KService::serviceByStorageId(storageId.toString())) {
apps.append(new FolioApplication(parent, service)); apps.append(std::make_shared<FolioApplication>(parent, service));
} }
} }
FolioApplicationFolder *folder = new FolioApplicationFolder(parent, name); FolioApplicationFolder::Ptr folder = std::make_shared<FolioApplicationFolder>(parent, name);
folder->setApplications(apps); folder->setApplications(apps);
return folder; return folder;
} }
@ -69,7 +69,7 @@ QList<FolioApplication *> FolioApplicationFolder::appPreviews()
if (!m_delegates[i].delegate->application()) { if (!m_delegates[i].delegate->application()) {
continue; continue;
} }
previews.push_back(m_delegates[i].delegate->application()); previews.push_back(m_delegates[i].delegate->application().get());
} }
return previews; return previews;
} }
@ -79,15 +79,15 @@ ApplicationFolderModel *FolioApplicationFolder::applications()
return m_applicationFolderModel; return m_applicationFolderModel;
} }
void FolioApplicationFolder::setApplications(QList<FolioApplication *> applications) void FolioApplicationFolder::setApplications(QList<FolioApplication::Ptr> applications)
{ {
if (m_applicationFolderModel) { if (m_applicationFolderModel) {
m_applicationFolderModel->deleteLater(); m_applicationFolderModel->deleteLater();
} }
m_delegates.clear(); m_delegates.clear();
for (auto *app : applications) { for (FolioApplication::Ptr app : applications) {
m_delegates.append({new FolioDelegate{app, m_homeScreen}, 0, 0}); m_delegates.append({FolioDelegate::Ptr{new FolioDelegate{app, m_homeScreen}}, 0, 0, 0});
} }
m_applicationFolderModel = new ApplicationFolderModel{this}; m_applicationFolderModel = new ApplicationFolderModel{this};
m_applicationFolderModel->evaluateDelegateIndexes(); m_applicationFolderModel->evaluateDelegateIndexes();
@ -102,7 +102,7 @@ void FolioApplicationFolder::moveEntry(int fromRow, int toRow)
m_applicationFolderModel->moveEntry(fromRow, 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); return m_applicationFolderModel->addDelegate(delegate, row);
} }
@ -122,11 +122,11 @@ bool FolioApplicationFolder::isDropPositionOutside(qreal x, qreal y)
return m_applicationFolderModel->isDropPositionOutside(x, y); return m_applicationFolderModel->isDropPositionOutside(x, y);
} }
ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *folder) ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *parent)
: QAbstractListModel{folder} : QAbstractListModel{parent}
, m_folder{folder} , m_folder{parent}
{ {
HomeScreenState *homeScreenState = folder->m_homeScreen->homeScreenState(); HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() { connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() {
evaluateDelegateIndexes(); evaluateDelegateIndexes();
}); });
@ -166,7 +166,7 @@ QVariant ApplicationFolderModel::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case DelegateRole: 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: case columnIndexRole:
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).columnIndex); return QVariant::fromValue(m_folder->m_delegates.at(index.row()).columnIndex);
case rowIndexRole: case rowIndexRole:
@ -183,7 +183,7 @@ QHash<int, QByteArray> ApplicationFolderModel::roleNames() const
return {{DelegateRole, "delegate"}, {columnIndexRole, "columnIndex"}, {rowIndexRole, "rowIndex"}, {pageIndexRole, "pageIndex"}}; 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()) { if (index < 0 || index >= m_folder->m_delegates.size()) {
return nullptr; return nullptr;
@ -217,7 +217,7 @@ void ApplicationFolderModel::moveEntry(int fromRow, int toRow)
Q_EMIT m_folder->saveRequested(); 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()) { if (index < 0 || index > m_folder->m_delegates.size()) {
return false; return false;
@ -230,7 +230,7 @@ bool ApplicationFolderModel::canAddDelegate(FolioDelegate *delegate, int index)
return true; return true;
} }
bool ApplicationFolderModel::addDelegate(FolioDelegate *delegate, int index) bool ApplicationFolderModel::addDelegate(FolioDelegate::Ptr delegate, int index)
{ {
if (!canAddDelegate(delegate, index)) { if (!canAddDelegate(delegate, index)) {
return false; return false;
@ -238,14 +238,14 @@ bool ApplicationFolderModel::addDelegate(FolioDelegate *delegate, int index)
if (index == m_folder->m_delegates.size()) { if (index == m_folder->m_delegates.size()) {
beginInsertRows(QModelIndex(), index, index); beginInsertRows(QModelIndex(), index, index);
m_folder->m_delegates.append({delegate, 0, 0}); m_folder->m_delegates.append({delegate, 0, 0, 0});
evaluateDelegateIndexes(false); evaluateDelegateIndexes(false);
endInsertRows(); endInsertRows();
} else if (m_folder->m_delegates[index].delegate->type() == FolioDelegate::None) { } else if (m_folder->m_delegates[index].delegate->type() == FolioDelegate::None) {
replaceGhostEntry(delegate); replaceGhostEntry(delegate);
} else { } else {
beginInsertRows(QModelIndex(), index, index); 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); evaluateDelegateIndexes(false);
endInsertRows(); endInsertRows();
} }
@ -309,7 +309,7 @@ int ApplicationFolderModel::getGhostEntryPosition()
void ApplicationFolderModel::setGhostEntry(int index) void ApplicationFolderModel::setGhostEntry(int index)
{ {
FolioDelegate *ghost = nullptr; FolioDelegate::Ptr ghost = nullptr;
// check if a ghost entry already exists // check if a ghost entry already exists
for (int i = 0; i < m_folder->m_delegates.size(); i++) { for (int i = 0; i < m_folder->m_delegates.size(); i++) {
@ -328,14 +328,14 @@ void ApplicationFolderModel::setGhostEntry(int index)
} }
if (!ghost) { if (!ghost) {
ghost = new FolioDelegate{m_folder->m_homeScreen}; ghost = std::make_shared<FolioDelegate>(m_folder->m_homeScreen);
} }
// add empty delegate at new position // add empty delegate at new position
addDelegate(ghost, index); 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++) { for (int i = 0; i < m_folder->m_delegates.size(); i++) {
if (m_folder->m_delegates[i].delegate->type() == FolioDelegate::None) { if (m_folder->m_delegates[i].delegate->type() == FolioDelegate::None) {

View file

@ -28,7 +28,7 @@ class FolioApplication;
* @short Object that represents an application folder. * @short Object that represents an application folder.
*/ */
class FolioApplicationFolder : public QObject class FolioApplicationFolder : public QObject, public std::enable_shared_from_this<FolioApplicationFolder>
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 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) Q_PROPERTY(ApplicationFolderModel *applications READ applications NOTIFY applicationsReset)
public: public:
typedef std::shared_ptr<FolioApplicationFolder> Ptr;
FolioApplicationFolder(HomeScreen *parent = nullptr, QString name = QString{}); FolioApplicationFolder(HomeScreen *parent = nullptr, QString name = QString{});
static FolioApplicationFolder *fromJson(QJsonObject &obj, HomeScreen *parent); static std::shared_ptr<FolioApplicationFolder> fromJson(QJsonObject &obj, HomeScreen *parent);
QJsonObject toJson() const; QJsonObject toJson() const;
QString name() const; QString name() const;
@ -47,10 +49,10 @@ public:
QList<FolioApplication *> appPreviews(); QList<FolioApplication *> appPreviews();
ApplicationFolderModel *applications(); ApplicationFolderModel *applications();
void setApplications(QList<FolioApplication *> applications); void setApplications(QList<std::shared_ptr<FolioApplication>> applications);
void moveEntry(int fromRow, int toRow); void moveEntry(int fromRow, int toRow);
bool addDelegate(FolioDelegate *delegate, int row); bool addDelegate(std::shared_ptr<FolioDelegate> delegate, int row);
Q_INVOKABLE void removeDelegate(int row); Q_INVOKABLE void removeDelegate(int row);
int dropInsertPosition(int page, qreal x, qreal y); int dropInsertPosition(int page, qreal x, qreal y);
@ -73,7 +75,7 @@ private:
}; };
struct ApplicationDelegate { struct ApplicationDelegate {
FolioDelegate *delegate; std::shared_ptr<FolioDelegate> delegate;
int columnIndex; int columnIndex;
int rowIndex; int rowIndex;
int pageIndex; int pageIndex;
@ -91,16 +93,16 @@ public:
rowIndexRole, rowIndexRole,
pageIndexRole, pageIndexRole,
}; };
ApplicationFolderModel(FolioApplicationFolder *folder); ApplicationFolderModel(FolioApplicationFolder *parent);
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
FolioDelegate *getDelegate(int index); std::shared_ptr<FolioDelegate> getDelegate(int index);
void moveEntry(int fromRow, int toRow); void moveEntry(int fromRow, int toRow);
bool canAddDelegate(FolioDelegate *delegate, int index); bool canAddDelegate(std::shared_ptr<FolioDelegate> delegate, int index);
bool addDelegate(FolioDelegate *delegate, int index); bool addDelegate(std::shared_ptr<FolioDelegate> delegate, int index);
void removeDelegate(int index); void removeDelegate(int index);
QPointF getDelegatePosition(int index); QPointF getDelegatePosition(int index);
@ -109,7 +111,7 @@ public:
// invisible - existing delegate looks like it doesn't exist // invisible - existing delegate looks like it doesn't exist
int getGhostEntryPosition(); int getGhostEntryPosition();
void setGhostEntry(int index); void setGhostEntry(int index);
void replaceGhostEntry(FolioDelegate *delegate); void replaceGhostEntry(std::shared_ptr<FolioDelegate> delegate);
void deleteGhostEntry(); void deleteGhostEntry();
// the index that dropping at the position given would place the delegate at. // the index that dropping at the position given would place the delegate at.

View file

@ -13,7 +13,7 @@ FolioDelegate::FolioDelegate(HomeScreen *parent)
{ {
} }
FolioDelegate::FolioDelegate(FolioApplication *application, HomeScreen *parent) FolioDelegate::FolioDelegate(FolioApplication::Ptr application, HomeScreen *parent)
: QObject{parent} : QObject{parent}
, m_type{FolioDelegate::Application} , m_type{FolioDelegate::Application}
, m_application{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} : QObject{parent}
, m_type{FolioDelegate::Folder} , m_type{FolioDelegate::Folder}
, m_application{nullptr} , 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} : QObject{parent}
, m_type{FolioDelegate::Widget} , m_type{FolioDelegate::Widget}
, m_application{nullptr} , 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(); const QString type = obj[QStringLiteral("type")].toString();
if (type == "application") { if (type == "application") {
// read application // read application
FolioApplication *app = FolioApplication::fromJson(obj, parent); FolioApplication::Ptr app = FolioApplication::fromJson(obj, parent);
if (app) { if (app) {
return new FolioDelegate{app, parent}; return std::make_shared<FolioDelegate>(app, parent);
} }
} else if (type == "folder") { } else if (type == "folder") {
// read folder // read folder
FolioApplicationFolder *folder = FolioApplicationFolder::fromJson(obj, parent); FolioApplicationFolder::Ptr folder = FolioApplicationFolder::fromJson(obj, parent);
if (folder) { if (folder) {
return new FolioDelegate{folder, parent}; return std::make_shared<FolioDelegate>(folder, parent);
} }
} else if (type == "widget") { } else if (type == "widget") {
// read widget // read widget
FolioWidget *widget = FolioWidget::fromJson(obj, parent); FolioWidget::Ptr widget = FolioWidget::fromJson(obj, parent);
if (widget) { if (widget) {
return new FolioDelegate{widget, parent}; return std::make_shared<FolioDelegate>(widget, parent);
} }
} else if (type == "none") { } else if (type == "none") {
return new FolioDelegate{parent}; return std::make_shared<FolioDelegate>(parent);
} }
return nullptr; return nullptr;
@ -93,26 +93,41 @@ QJsonObject FolioDelegate::toJson() const
return QJsonObject{}; return QJsonObject{};
} }
FolioDelegate::Type FolioDelegate::type() FolioDelegate::Type FolioDelegate::type() const
{ {
return m_type; return m_type;
} }
FolioApplication *FolioDelegate::application() FolioApplication::Ptr FolioDelegate::application()
{ {
return m_application; return m_application;
} }
FolioApplicationFolder *FolioDelegate::folder() FolioApplication *FolioDelegate::applicationRaw()
{
return m_application.get();
}
FolioApplicationFolder::Ptr FolioDelegate::folder()
{ {
return m_folder; return m_folder;
} }
FolioWidget *FolioDelegate::widget() FolioApplicationFolder *FolioDelegate::folderRaw()
{
return m_folder.get();
}
FolioWidget::Ptr FolioDelegate::widget()
{ {
return m_widget; return m_widget;
} }
FolioWidget *FolioDelegate::widgetRaw()
{
return m_widget.get();
}
FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent) FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent)
: FolioDelegate{parent} : FolioDelegate{parent}
, m_homeScreen{parent} , m_homeScreen{parent}
@ -122,7 +137,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, HomeScreen *parent)
init(); 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} : FolioDelegate{application, parent}
, m_homeScreen{parent} , m_homeScreen{parent}
, m_row{row} , m_row{row}
@ -131,7 +146,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplication *appl
init(); 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} : FolioDelegate{folder, parent}
, m_homeScreen{parent} , m_homeScreen{parent}
, m_row{row} , m_row{row}
@ -140,7 +155,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioApplicationFolder
init(); 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} : FolioDelegate{widget, parent}
, m_homeScreen{parent} , m_homeScreen{parent}
, m_row{row} , m_row{row}
@ -149,7 +164,7 @@ FolioPageDelegate::FolioPageDelegate(int row, int column, FolioWidget *widget, H
init(); init();
} }
FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate *delegate, HomeScreen *parent) FolioPageDelegate::FolioPageDelegate(int row, int column, FolioDelegate::Ptr delegate, HomeScreen *parent)
: FolioDelegate{parent} : FolioDelegate{parent}
, m_homeScreen{parent} , m_homeScreen{parent}
, m_row{row} , m_row{row}
@ -207,21 +222,21 @@ void FolioPageDelegate::init()
} }
if (m_widget) { 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_realRow += rowOffset;
m_realColumn += columnOffset; m_realColumn += columnOffset;
}); });
} }
connect(homeScreenState, &HomeScreenState::pageOrientationChanged, this, [this]() { connect(homeScreenState, &HomeScreenState::pageOrientationChanged, this, [this]() {
setRowOnly(getTranslatedTopLeftRow(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)); 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) { if (!fd) {
return nullptr; return nullptr;
@ -233,13 +248,13 @@ FolioPageDelegate *FolioPageDelegate::fromJson(QJsonObject &obj, HomeScreen *par
int row = getTranslatedTopLeftRow(parent, realRow, realColumn, fd); int row = getTranslatedTopLeftRow(parent, realRow, realColumn, fd);
int column = getTranslatedTopLeftColumn(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<FolioPageDelegate>(row, column, fd, parent);
fd->deleteLater(); fd->deleteLater();
return delegate; 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 row = getTranslatedRow(homeScreen, realRow, realColumn);
int column = getTranslatedColumn(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 row = getTranslatedRow(homeScreen, realRow, realColumn);
int column = getTranslatedColumn(homeScreen, realRow, realColumn); int column = getTranslatedColumn(homeScreen, realRow, realColumn);
@ -386,3 +401,8 @@ void FolioPageDelegate::setColumnOnly(int column)
Q_EMIT columnChanged(); Q_EMIT columnChanged();
} }
} }
std::shared_ptr<FolioPageDelegate> FolioPageDelegate::sharedPageDelegate()
{
return static_pointer_cast<FolioPageDelegate>(shared_from_this());
}

View file

@ -15,15 +15,17 @@ class FolioApplication;
class FolioApplicationFolder; class FolioApplicationFolder;
class FolioWidget; class FolioWidget;
class FolioDelegate : public QObject class FolioDelegate : public QObject, public std::enable_shared_from_this<FolioDelegate>
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(FolioDelegate::Type type READ type CONSTANT) Q_PROPERTY(FolioDelegate::Type type READ type CONSTANT)
Q_PROPERTY(FolioApplication *application READ application CONSTANT) Q_PROPERTY(FolioApplication *application READ applicationRaw CONSTANT)
Q_PROPERTY(FolioApplicationFolder *folder READ folder CONSTANT) Q_PROPERTY(FolioApplicationFolder *folder READ folderRaw CONSTANT)
Q_PROPERTY(FolioWidget *widget READ widget CONSTANT) Q_PROPERTY(FolioWidget *widget READ widgetRaw CONSTANT)
public: public:
typedef std::shared_ptr<FolioDelegate> Ptr;
enum Type { enum Type {
None, None,
Application, Application,
@ -32,25 +34,31 @@ public:
}; };
Q_ENUM(Type) Q_ENUM(Type)
FolioDelegate(HomeScreen *parent = nullptr); FolioDelegate(HomeScreen *parent);
FolioDelegate(FolioApplication *application, HomeScreen *parent); FolioDelegate(std::shared_ptr<FolioApplication> application, HomeScreen *parent);
FolioDelegate(FolioApplicationFolder *folder, HomeScreen *parent); FolioDelegate(std::shared_ptr<FolioApplicationFolder> folder, HomeScreen *parent);
FolioDelegate(FolioWidget *widget, HomeScreen *parent); FolioDelegate(std::shared_ptr<FolioWidget> widget, HomeScreen *parent);
static FolioDelegate *fromJson(QJsonObject &obj, HomeScreen *parent); static std::shared_ptr<FolioDelegate> fromJson(QJsonObject &obj, HomeScreen *parent);
virtual QJsonObject toJson() const; virtual QJsonObject toJson() const;
FolioDelegate::Type type(); FolioDelegate::Type type() const;
FolioApplication *application();
FolioApplicationFolder *folder(); std::shared_ptr<FolioApplication> application();
FolioWidget *widget(); FolioApplication *applicationRaw();
std::shared_ptr<FolioApplicationFolder> folder();
FolioApplicationFolder *folderRaw();
std::shared_ptr<FolioWidget> widget();
FolioWidget *widgetRaw();
protected: protected:
FolioDelegate::Type m_type; FolioDelegate::Type m_type;
FolioApplication *m_application{nullptr}; std::shared_ptr<FolioApplication> m_application{nullptr};
FolioApplicationFolder *m_folder{nullptr}; std::shared_ptr<FolioApplicationFolder> m_folder{nullptr};
FolioWidget *m_widget{nullptr}; std::shared_ptr<FolioWidget> m_widget{nullptr};
}; };
class FolioPageDelegate : public FolioDelegate class FolioPageDelegate : public FolioDelegate
@ -61,15 +69,17 @@ class FolioPageDelegate : public FolioDelegate
QML_UNCREATABLE("") QML_UNCREATABLE("")
public: public:
FolioPageDelegate(int row = 0, int column = 0, HomeScreen *parent = nullptr); typedef std::shared_ptr<FolioPageDelegate> Ptr;
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);
static FolioPageDelegate *fromJson(QJsonObject &obj, HomeScreen *parent); FolioPageDelegate(int row = 0, int column = 0, HomeScreen *parent = nullptr);
static int getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd); FolioPageDelegate(int row, int column, std::shared_ptr<FolioApplication> application, HomeScreen *parent);
static int getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, FolioDelegate *fd); FolioPageDelegate(int row, int column, std::shared_ptr<FolioApplicationFolder> folder, HomeScreen *parent);
FolioPageDelegate(int row, int column, std::shared_ptr<FolioWidget> widget, HomeScreen *parent);
FolioPageDelegate(int row, int column, std::shared_ptr<FolioDelegate> delegate, HomeScreen *parent);
static std::shared_ptr<FolioPageDelegate> fromJson(QJsonObject &obj, HomeScreen *parent);
static int getTranslatedTopLeftRow(HomeScreen *homeScreen, int realRow, int realColumn, std::shared_ptr<FolioDelegate> fd);
static int getTranslatedTopLeftColumn(HomeScreen *homeScreen, int realRow, int realColumn, std::shared_ptr<FolioDelegate> fd);
static int getTranslatedRow(HomeScreen *homeScreen, int realRow, int realColumn); static int getTranslatedRow(HomeScreen *homeScreen, int realRow, int realColumn);
static int getTranslatedColumn(HomeScreen *homeScreen, int realRow, int realColumn); static int getTranslatedColumn(HomeScreen *homeScreen, int realRow, int realColumn);
@ -81,6 +91,8 @@ public:
int column(); int column();
void setColumn(int column); void setColumn(int column);
std::shared_ptr<FolioPageDelegate> sharedPageDelegate();
Q_SIGNALS: Q_SIGNALS:
void rowChanged(); void rowChanged();
void columnChanged(); void columnChanged();

View file

@ -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 id = obj[QStringLiteral("id")].toInt();
int gridWidth = obj[QStringLiteral("gridWidth")].toInt(); int gridWidth = obj[QStringLiteral("gridWidth")].toInt();
int gridHeight = obj[QStringLiteral("gridHeight")].toInt(); int gridHeight = obj[QStringLiteral("gridHeight")].toInt();
return new FolioWidget(parent, id, gridWidth, gridHeight); return std::make_shared<FolioWidget>(parent, id, gridWidth, gridHeight);
} }
QJsonObject FolioWidget::toJson() const 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); 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) { if (!otherWidget) {
return false; return false;

View file

@ -22,7 +22,7 @@ public:
/** /**
* @short Object that represents a widget on the homescreen. * @short Object that represents a widget on the homescreen.
*/ */
class FolioWidget : public QObject class FolioWidget : public QObject, public std::enable_shared_from_this<FolioWidget>
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int id READ id NOTIFY idChanged) 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) Q_PROPERTY(PlasmaQuick::AppletQuickItem *visualApplet READ visualApplet NOTIFY visualAppletChanged)
public: public:
typedef std::shared_ptr<FolioWidget> Ptr;
FolioWidget(HomeScreen *parent = nullptr, int id = -1, int gridWidth = 0, int gridHeight = 0); FolioWidget(HomeScreen *parent = nullptr, int id = -1, int gridWidth = 0, int gridHeight = 0);
FolioWidget(HomeScreen *parent, Plasma::Applet *applet, int gridWidth, int gridHeight); FolioWidget(HomeScreen *parent, Plasma::Applet *applet, int gridWidth, int gridHeight);
static FolioWidget *fromJson(QJsonObject &obj, HomeScreen *parent); static std::shared_ptr<FolioWidget> fromJson(QJsonObject &obj, HomeScreen *parent);
QJsonObject toJson() const; QJsonObject toJson() const;
int id() const; int id() const;
@ -59,7 +61,7 @@ public:
// query whether (row, column) is inside this widget, if it was at position (widgetRow, widgetColumn) // 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 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<FolioWidget> otherWidget, int otherWidgetRow, int otherWidgetColumn);
Plasma::Applet *applet() const; Plasma::Applet *applet() const;
void setApplet(Plasma::Applet *applet); void setApplet(Plasma::Applet *applet);

View file

@ -517,12 +517,17 @@ void HomeScreenState::setFolderOpenProgress(qreal folderOpenProgress)
} }
} }
FolioApplicationFolder *HomeScreenState::currentFolder() const FolioApplicationFolder::Ptr HomeScreenState::currentFolder() const
{ {
return m_currentFolder; 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) { if (m_currentFolder != folder) {
m_currentFolder = folder; m_currentFolder = folder;
@ -662,17 +667,17 @@ FolioDelegate *HomeScreenState::getPageDelegateAt(int page, int row, int column)
return nullptr; return nullptr;
} }
FolioDelegate *delegate = pageModel->getDelegate(row, column); FolioDelegate::Ptr delegate = pageModel->getDelegate(row, column);
if (!delegate) { if (!delegate) {
return nullptr; return nullptr;
} }
return delegate; return delegate.get();
} }
FolioDelegate *HomeScreenState::getFavouritesDelegateAt(int position) FolioDelegate *HomeScreenState::getFavouritesDelegateAt(int position)
{ {
return m_homeScreen->favouritesModel()->getEntryAt(position); return m_homeScreen->favouritesModel()->getEntryAt(position).get();
} }
FolioDelegate *HomeScreenState::getFolderDelegateAt(int position) FolioDelegate *HomeScreenState::getFolderDelegateAt(int position)
@ -681,7 +686,7 @@ FolioDelegate *HomeScreenState::getFolderDelegateAt(int position)
return nullptr; return nullptr;
} }
return m_currentFolder->applications()->getDelegate(position); return m_currentFolder->applications()->getDelegate(position).get();
} }
QPointF HomeScreenState::getPageDelegateScreenPosition(int page, int row, int column) 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) void HomeScreenState::openFolder(qreal delegateX, qreal delegateY, FolioApplicationFolder *folder)
{ {
setCurrentFolder(folder); setCurrentFolder(folder->shared_from_this());
m_openFolderAnim->stop(); m_openFolderAnim->stop();
m_closeFolderAnim->stop(); m_closeFolderAnim->stop();

View file

@ -60,7 +60,7 @@ class HomeScreenState : public QObject
Q_PROPERTY(qreal folderPageContentWidth READ folderPageContentWidth WRITE setFolderPageContentWidth NOTIFY folderPageContentWidthChanged) Q_PROPERTY(qreal folderPageContentWidth READ folderPageContentWidth WRITE setFolderPageContentWidth NOTIFY folderPageContentWidthChanged)
Q_PROPERTY(qreal folderPageContentHeight READ folderPageContentHeight WRITE setFolderPageContentHeight NOTIFY folderPageContentHeightChanged) Q_PROPERTY(qreal folderPageContentHeight READ folderPageContentHeight WRITE setFolderPageContentHeight NOTIFY folderPageContentHeightChanged)
Q_PROPERTY(qreal folderOpenProgress READ folderOpenProgress WRITE setFolderOpenProgress NOTIFY folderOpenProgressChanged) 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 folderGridLength READ folderGridLength NOTIFY folderGridLengthChanged)
Q_PROPERTY(qreal settingsOpenProgress READ settingsOpenProgress WRITE setSettingsOpenProgress NOTIFY settingsOpenProgressChanged) Q_PROPERTY(qreal settingsOpenProgress READ settingsOpenProgress WRITE setSettingsOpenProgress NOTIFY settingsOpenProgressChanged)
@ -208,8 +208,9 @@ public:
int folderGridLength() const; int folderGridLength() const;
void calculateFolderGridLength(); void calculateFolderGridLength();
FolioApplicationFolder *currentFolder() const; std::shared_ptr<FolioApplicationFolder> currentFolder() const;
void setCurrentFolder(FolioApplicationFolder *folder); FolioApplicationFolder *currentFolderRaw() const;
void setCurrentFolder(std::shared_ptr<FolioApplicationFolder> folder);
// the progress for the opening of the settings view // the progress for the opening of the settings view
qreal settingsOpenProgress(); qreal settingsOpenProgress();
@ -389,7 +390,7 @@ private:
qreal m_folderPageContentWidth{0}; qreal m_folderPageContentWidth{0};
qreal m_folderPageContentHeight{0}; qreal m_folderPageContentHeight{0};
qreal m_folderOpenProgress{0}; qreal m_folderOpenProgress{0};
FolioApplicationFolder *m_currentFolder{nullptr}; std::shared_ptr<FolioApplicationFolder> m_currentFolder{nullptr};
int m_folderGridLength{0}; int m_folderGridLength{0};
qreal m_settingsOpenProgress{0}; qreal m_settingsOpenProgress{0};

View file

@ -6,7 +6,7 @@
#include "homescreenstate.h" #include "homescreenstate.h"
#include "widgetsmanager.h" #include "widgetsmanager.h"
PageModel::PageModel(QList<FolioPageDelegate *> delegates, QObject *parent, HomeScreen *homeScreen) PageModel::PageModel(QList<FolioPageDelegate::Ptr> delegates, QObject *parent, HomeScreen *homeScreen)
: QAbstractListModel{parent} : QAbstractListModel{parent}
, m_homeScreen{homeScreen} , m_homeScreen{homeScreen}
, m_delegates{delegates} , m_delegates{delegates}
@ -15,7 +15,7 @@ PageModel::PageModel(QList<FolioPageDelegate *> delegates, QObject *parent, Home
if (applet) { if (applet) {
// delete any instance of this widget // delete any instance of this widget
for (int i = 0; i < m_delegates.size(); i++) { 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) { if (delegate->type() == FolioDelegate::Widget && delegate->widget()->applet() == applet) {
removeDelegate(i); removeDelegate(i);
break; break;
@ -29,12 +29,12 @@ PageModel::~PageModel() = default;
PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen) PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen)
{ {
QList<FolioPageDelegate *> delegates; QList<FolioPageDelegate::Ptr> delegates;
for (QJsonValueRef r : arr) { for (QJsonValueRef r : arr) {
QJsonObject obj = r.toObject(); QJsonObject obj = r.toObject();
FolioPageDelegate *delegate = FolioPageDelegate::fromJson(obj, homeScreen); FolioPageDelegate::Ptr delegate = FolioPageDelegate::fromJson(obj, homeScreen);
if (delegate) { if (delegate) {
delegates.append(delegate); delegates.append(delegate);
} }
@ -43,7 +43,7 @@ PageModel *PageModel::fromJson(QJsonArray &arr, QObject *parent, HomeScreen *hom
PageModel *model = new PageModel{delegates, parent, homeScreen}; PageModel *model = new PageModel{delegates, parent, homeScreen};
// ensure delegates can request saves // ensure delegates can request saves
for (auto *delegate : delegates) { for (FolioPageDelegate::Ptr delegate : delegates) {
model->connectSaveRequests(delegate); model->connectSaveRequests(delegate);
} }
@ -54,7 +54,7 @@ QJsonArray PageModel::toJson() const
{ {
QJsonArray arr; QJsonArray arr;
for (FolioPageDelegate *delegate : m_delegates) { for (FolioPageDelegate::Ptr delegate : m_delegates) {
if (!delegate) { if (!delegate) {
continue; continue;
} }
@ -79,7 +79,7 @@ QVariant PageModel::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case DelegateRole: case DelegateRole:
return QVariant::fromValue(m_delegates.at(index.row())); return QVariant::fromValue(m_delegates.at(index.row()).get());
} }
return QVariant(); 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 // 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())) { if (delegate->widget()->isInBounds(row, column, d->row(), d->column())) {
return false; return false;
} else if (d->type() == FolioDelegate::Widget) { } else if (d->type() == FolioDelegate::Widget) {
@ -151,7 +151,7 @@ bool PageModel::canAddDelegate(int row, int column, FolioDelegate *delegate)
// inserting app or folder... // inserting app or folder...
// check if there already exists a delegate in this space // 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) { if (d->row() == row && d->column() == column) {
return false; return false;
} else if (d->type() == FolioDelegate::Widget && d->widget()->isInBounds(d->row(), d->column(), row, column)) { } 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; 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; return false;
} }
@ -180,9 +180,9 @@ bool PageModel::addDelegate(FolioPageDelegate *delegate)
return true; 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) { if (d->row() == row && d->column() == col) {
return d; return d;
} }
@ -207,23 +207,21 @@ void PageModel::moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int new
return; return;
} }
// test if we can add the delegate with new size and position // Test if we can add the delegate with new size and position
FolioWidget *testWidget = new FolioWidget(m_homeScreen, 0, 0, 0); FolioWidget::Ptr testWidget = std::make_shared<FolioWidget>(m_homeScreen, 0, 0, 0);
// we have to use setGridWidth and setGridHeight since it takes into account the page orientation // We have to use setGridWidth and setGridHeight since it takes into account the page orientation
testWidget->setGridWidth(newGridWidth); testWidget->setGridWidth(newGridWidth);
testWidget->setGridHeight(newGridHeight); testWidget->setGridHeight(newGridHeight);
FolioDelegate *testDelegate = new FolioDelegate(testWidget, m_homeScreen); FolioDelegate::Ptr testDelegate = std::make_shared<FolioDelegate>(testWidget, m_homeScreen);
// testWidget and testDelegate will get cleaned up automatically since are smart pointers
// NOT THREAD SAFE! // NOT THREAD SAFE!
// which is fine, because the GUI isn't multithreaded // 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 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); bool canAdd = canAddDelegate(newRow, newColumn, testDelegate.get());
m_delegates.insert(index, delegate); // add it back m_delegates.insert(index, delegate->sharedPageDelegate()); // add it back
// cleanup test delegate
testDelegate->deleteLater();
testWidget->deleteLater();
if (!canAdd) { if (!canAdd) {
return; return;
@ -240,12 +238,12 @@ bool PageModel::isPageEmpty()
return m_delegates.size() == 0; return m_delegates.size() == 0;
} }
void PageModel::connectSaveRequests(FolioDelegate *delegate) void PageModel::connectSaveRequests(FolioDelegate::Ptr delegate)
{ {
if (delegate->type() == FolioDelegate::Folder && delegate->folder()) { 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()) { } 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);
} }
} }

View file

@ -29,7 +29,9 @@ public:
ShownRole, ShownRole,
}; };
PageModel(QList<FolioPageDelegate *> delegates = QList<FolioPageDelegate *>{}, QObject *parent = nullptr, HomeScreen *m_homeScreen = nullptr); PageModel(QList<std::shared_ptr<FolioPageDelegate>> delegates = QList<std::shared_ptr<FolioPageDelegate>>{},
QObject *parent = nullptr,
HomeScreen *m_homeScreen = nullptr);
~PageModel(); ~PageModel();
static PageModel *fromJson(QJsonArray &arr, QObject *parent, HomeScreen *homeScreen); 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 row, int col);
Q_INVOKABLE void removeDelegate(int index); Q_INVOKABLE void removeDelegate(int index);
Q_INVOKABLE bool canAddDelegate(int row, int column, FolioDelegate *delegate); Q_INVOKABLE bool canAddDelegate(int row, int column, FolioDelegate *delegate);
bool addDelegate(FolioPageDelegate *delegate); bool addDelegate(std::shared_ptr<FolioPageDelegate> delegate);
FolioPageDelegate *getDelegate(int row, int col); std::shared_ptr<FolioPageDelegate> getDelegate(int row, int col);
Q_INVOKABLE void moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int newRow, int newColumn, int newGridWidth, int newGridHeight); Q_INVOKABLE void moveAndResizeWidgetDelegate(FolioPageDelegate *delegate, int newRow, int newColumn, int newGridWidth, int newGridHeight);
@ -57,8 +59,8 @@ Q_SIGNALS:
void saveRequested(); void saveRequested();
private: private:
void connectSaveRequests(FolioDelegate *delegate); void connectSaveRequests(std::shared_ptr<FolioDelegate> delegate);
HomeScreen *m_homeScreen{nullptr}; HomeScreen *m_homeScreen{nullptr};
QList<FolioPageDelegate *> m_delegates; QList<std::shared_ptr<FolioPageDelegate>> m_delegates;
}; };