File indexing completed on 2024-04-21 04:50:52

0001 /*
0002     SPDX-FileCopyrightText: 2017 Nicolas Carion
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #pragma once
0007 
0008 #include "undohelper.hpp"
0009 #include <QAbstractItemModel>
0010 #include <memory>
0011 #include <unordered_map>
0012 
0013 /** @class AbstractTreeModel
0014     @brief This class represents a generic tree hierarchy
0015  */
0016 class TreeItem;
0017 class AbstractTreeModel : public QAbstractItemModel, public std::enable_shared_from_this<AbstractTreeModel>
0018 {
0019     Q_OBJECT
0020 
0021 public:
0022     /** @brief Construct a TreeModel
0023        @param parent is the parent object of the model
0024        @return a ptr to the created object
0025     */
0026     static std::shared_ptr<AbstractTreeModel> construct(QObject *parent = nullptr);
0027 
0028 protected:
0029     // This is protected. Call construct instead.
0030     explicit AbstractTreeModel(QObject *parent = nullptr);
0031 
0032 public:
0033     ~AbstractTreeModel() override;
0034 
0035     /** @brief Given an item from the hierarchy, construct the corresponding ModelIndex */
0036     QModelIndex getIndexFromItem(const std::shared_ptr<TreeItem> &item, int column = 0) const;
0037 
0038     /** @brief Given an item id, construct the corresponding ModelIndex */
0039     QModelIndex getIndexFromId(int id) const;
0040 
0041     /** @brief Return a ptr to an item given its id */
0042     std::shared_ptr<TreeItem> getItemById(int id) const;
0043 
0044     /** @brief Return a ptr to the root of the tree */
0045     std::shared_ptr<TreeItem> getRoot() const;
0046 
0047     QVariant data(const QModelIndex &index, int role) const override;
0048     // This is reimplemented to prevent selection of the categories
0049     Qt::ItemFlags flags(const QModelIndex &index) const override;
0050     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
0051     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
0052     QModelIndex parent(const QModelIndex &index) const override;
0053     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0054     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
0055 
0056     /** @brief Helper function to generate a lambda that adds an item to the tree */
0057     Fun addItem_lambda(const std::shared_ptr<TreeItem> &new_item, int parentId);
0058 
0059     /** @brief Helper function to generate a lambda that removes an item from the tree */
0060     Fun removeItem_lambda(int id);
0061 
0062     /** @brief Helper function to generate a lambda that changes the row of an item */
0063     Fun moveItem_lambda(int id, int destRow, bool force = false);
0064 
0065     friend class TreeItem;
0066     friend class AbstractProjectItem;
0067 
0068 protected:
0069     /** @brief Register a new item. This is a call-back meant to be called from TreeItem */
0070     virtual void registerItem(const std::shared_ptr<TreeItem> &item);
0071 
0072     /** @brief Deregister an item. This is a call-back meant to be called from TreeItem */
0073     virtual void deregisterItem(int id, TreeItem *item);
0074 
0075     /** @brief Returns the next valid id to give to a new element */
0076     static int getNextId();
0077 
0078     /** @brief Send the appropriate notification related to a row that we are appending
0079        @param item is the parent item to which row is appended
0080     */
0081     void notifyRowAboutToAppend(const std::shared_ptr<TreeItem> &item);
0082 
0083     /** @brief Send the appropriate notification related to a row that we have appended
0084        @param row is the new element
0085     */
0086     void notifyRowAppended(const std::shared_ptr<TreeItem> &row);
0087 
0088     /** @brief Send the appropriate notification related to a row that we are deleting
0089        @param item is the parent of the row being deleted
0090        @param row is the index of the row being deleted
0091     */
0092     void notifyRowAboutToDelete(std::shared_ptr<TreeItem> item, int row);
0093 
0094     /** @brief Send the appropriate notification related to a row that we have appended
0095        @param row is the old element
0096     */
0097     void notifyRowDeleted();
0098 
0099     /** @brief This is a convenience function that helps check if the tree is in a valid state */
0100     virtual bool checkConsistency();
0101 
0102 protected:
0103     std::shared_ptr<TreeItem> rootItem;
0104 
0105     std::unordered_map<int, std::weak_ptr<TreeItem>> m_allItems;
0106 
0107     static int currentTreeId;
0108 };