#pragma once #include "lts_abstract_table_model.h" namespace LtsWidgets { template class LtsCheckableTableModel : public LtsAbstractTableModel { public: LtsCheckableTableModel(const QVector &header, int checkableColumn, QObject *parent) : LtsAbstractTableModel(header, parent) , m_checkableColumn(checkableColumn) { } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (role == Qt::CheckStateRole && index.column() == m_checkableColumn && LtsAbstractTableModel::indexIsValid(index)) return LtsAbstractTableModel::m_vecData.at(index.row()).first ? Qt::Checked : Qt::Unchecked; return QVariant(); } bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override { if (role == Qt::CheckStateRole) { switchCheckbox(index); return true; } return QAbstractItemModel::setData(index, value, role); } Qt::ItemFlags flags(const QModelIndex &index) const override { Qt::ItemFlags flags(LtsWidgets::LtsAbstractTableModel::flags(index) & ~Qt::ItemIsSelectable); if (index.column() == m_checkableColumn) return flags.setFlag(Qt::ItemIsUserCheckable); return flags; } QVector getCheckedIds() const { QVector ids; for (int row = 0; row < LtsAbstractTableModel::rowCount(); ++row) { const T &entry = LtsAbstractTableModel::m_vecData.at(row); if (entry.first) ids << entry.second.id(); } return ids; } QVector getUncheckedIds() const { QVector ids; for (int row = 0; row < LtsAbstractTableModel::rowCount(); ++row) { const T &entry = LtsAbstractTableModel::m_vecData.at(row); if (!entry.first) ids << entry.second.id(); } return ids; } bool setChecked(const QVector &vecCheckedIds) { for (int row = 0; row < LtsAbstractTableModel::rowCount(); ++row) { T &entry = LtsAbstractTableModel::m_vecData[row]; bool bContains = vecCheckedIds.contains(entry.second.id()); if (entry.first != bContains) { entry.first = bContains; const QModelIndex idx(LtsAbstractTableModel::index(row, m_checkableColumn, QModelIndex())); emit LtsAbstractTableModel::dataChanged(idx, idx, {Qt::CheckStateRole}); } } return true; } bool isFiltered(const T &data, DataModification modType) const override { Q_UNUSED(data); Q_UNUSED(modType); return false; } public slots: void switchCheckbox(const QModelIndex &index) { auto entry = LtsAbstractTableModel::getRowData(index.row()); entry.first = !entry.first; LtsAbstractTableModel::setRowData(index.row(), entry); } void selectAll() { for (int row = 0; row < LtsAbstractTableModel::rowCount(); ++row) { T entry = LtsAbstractTableModel::m_vecData.at(row); entry.first = true; LtsAbstractTableModel::setRowData(row, entry); } } void unselectAll() { for (int row = 0; row < LtsAbstractTableModel::rowCount(); ++row) { T entry = LtsAbstractTableModel::m_vecData.at(row); entry.first = false; LtsAbstractTableModel::setRowData(row, entry); } } private: int m_checkableColumn; }; }