92 lines
2.9 KiB
C
92 lines
2.9 KiB
C
|
//
|
||
|
// Created by grimmauld on 03.03.24.
|
||
|
//
|
||
|
|
||
|
#ifndef SWAYMUX_ABSTRACTTREEMODEL_H
|
||
|
#define SWAYMUX_ABSTRACTTREEMODEL_H
|
||
|
|
||
|
#include <type_traits>
|
||
|
#include "AbstractTreeNode.h"
|
||
|
#include <QAbstractItemModel>
|
||
|
|
||
|
template<class T>
|
||
|
class AbstractTreeModel : public QAbstractItemModel {
|
||
|
static_assert(std::is_base_of<AbstractTreeNode<T>, T>::value,
|
||
|
"Tree model subject class is not derived from AbstractTreeNode");
|
||
|
|
||
|
public:
|
||
|
Q_DISABLE_COPY_MOVE(AbstractTreeModel)
|
||
|
|
||
|
explicit AbstractTreeModel(QObject *parent = nullptr): QAbstractItemModel(parent) {};
|
||
|
|
||
|
~AbstractTreeModel() override = default;
|
||
|
|
||
|
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override {
|
||
|
if (!index.isValid() || role != Qt::DisplayRole)
|
||
|
return {};
|
||
|
|
||
|
const auto *item = static_cast<const T *>(index.internalPointer());
|
||
|
return item->data(index.column());
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] Qt::ItemFlags flags(const QModelIndex &index) const override {
|
||
|
return index.isValid()
|
||
|
? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation,
|
||
|
int role = Qt::DisplayRole) const override {
|
||
|
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
|
||
|
return QVariant{};
|
||
|
|
||
|
return T{}.headerData(section);
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] QModelIndex index(int row, int column,
|
||
|
const QModelIndex &parent = {}) const override {
|
||
|
if (!hasIndex(row, column, parent))
|
||
|
return {};
|
||
|
|
||
|
const T *parentItem = parent.isValid()
|
||
|
? static_cast<T *>(parent.internalPointer())
|
||
|
: getRoot();
|
||
|
|
||
|
if (auto *childItem = parentItem->child(row))
|
||
|
return createIndex(row, column, childItem);
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] QModelIndex parent(const QModelIndex &index) const override {
|
||
|
if (!index.isValid())
|
||
|
return {};
|
||
|
|
||
|
auto *childItem = static_cast<T *>(index.internalPointer());
|
||
|
T *parentItem = childItem->parentItem();
|
||
|
|
||
|
return parentItem != getRoot()
|
||
|
? createIndex(parentItem->row(), 0, parentItem) : QModelIndex{};
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] int rowCount(const QModelIndex &parent = {}) const override {
|
||
|
if (parent.column() > 0)
|
||
|
return 0;
|
||
|
|
||
|
const T *parentItem = parent.isValid()
|
||
|
? static_cast<const T *>(parent.internalPointer())
|
||
|
: getRoot();
|
||
|
|
||
|
return parentItem->childCount();
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override {
|
||
|
if (parent.isValid())
|
||
|
return static_cast<T *>(parent.internalPointer())->columnCount();
|
||
|
return T{}.columnCount();
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] virtual const T* getRoot() const = 0;
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif //SWAYMUX_ABSTRACTTREEMODEL_H
|