File indexing completed on 2024-05-19 05:44:24

0001 /*
0002     hashmodel.h
0003 
0004     SPDX-FileCopyrightText: 2016-2022 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com>
0005     SPDX-FileContributor: Milian Wolff <milian.wolff@kdab.com>
0006 
0007    SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include <QAbstractTableModel>
0013 #include <QHash>
0014 #include <QVector>
0015 
0016 template <typename Rows, typename ModelImpl>
0017 class HashModel : public QAbstractTableModel
0018 {
0019 public:
0020     explicit HashModel(QObject* parent = nullptr)
0021         : QAbstractTableModel(parent)
0022     {
0023     }
0024     virtual ~HashModel() = default;
0025 
0026     int columnCount(const QModelIndex& parent = {}) const final override
0027     {
0028         return parent.isValid() ? 0 : numColumns();
0029     }
0030 
0031     int rowCount(const QModelIndex& parent = {}) const final override
0032     {
0033         return parent.isValid() ? 0 : m_keys.size();
0034     }
0035 
0036     QVariant headerData(int section, Qt::Orientation orientation = Qt::Horizontal,
0037                         int role = Qt::DisplayRole) const final override
0038     {
0039         if (section < 0 || section > numColumns() || orientation != Qt::Horizontal) {
0040             return {};
0041         }
0042 
0043         return headerCell(section, role);
0044     }
0045 
0046     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const final override
0047     {
0048         if (!hasIndex(index.row(), index.column(), index.parent())) {
0049             return {};
0050         }
0051 
0052         const auto& key = m_keys.value(index.row());
0053         const auto& value = m_values.value(index.row());
0054 
0055         return cell(index.column(), role, key, value);
0056     }
0057 
0058     QModelIndex indexForKey(const typename Rows::key_type& key, int column = 0) const
0059     {
0060         auto it = std::find(m_keys.begin(), m_keys.end(), key);
0061         if (it == m_keys.end()) {
0062             return {};
0063         }
0064         const int row = std::distance(m_keys.begin(), it);
0065         return index(row, column);
0066     }
0067 
0068 protected:
0069     void setRows(const Rows& rows)
0070     {
0071         beginResetModel();
0072         m_keys.reserve(rows.size());
0073         m_values.reserve(rows.size());
0074         m_keys.clear();
0075         m_values.clear();
0076         for (auto it = rows.constBegin(), end = rows.constEnd(); it != end; ++it) {
0077             m_keys.push_back(it.key());
0078             m_values.push_back(it.value());
0079         }
0080         endResetModel();
0081     }
0082 
0083     virtual QVariant headerCell(int column, int role) const = 0;
0084     virtual QVariant cell(int column, int role, const typename Rows::key_type& key,
0085                           const typename Rows::mapped_type& entry) const = 0;
0086     virtual int numColumns() const = 0;
0087 
0088     QVector<typename Rows::key_type> m_keys;
0089     QVector<typename Rows::mapped_type> m_values;
0090 };