40#include <QItemSelection>
42#include <QRegularExpression>
61 int r = sourceIndex.row(), c = sourceIndex.column();
62 int n = sourceModel()->columnCount();
68 int k = (n * (n - 1) / 2) - (n - r) * ((n - r) - 1) / 2 + c - r - 1;
76 int n = sourceModel()->columnCount();
77 int k = proxyIndex.row();
78 int r = n - 2 -
static_cast<int>(sqrt(-8 * k + 4 * n * (n - 1) - 7) / 2.0 - 0.5);
79 int c = k + r + 1 - n * (n - 1) / 2 + (n - r) * ((n - r) - 1) / 2;
80 return sourceModel()->index(r, c);
85 int n = sourceModel()->rowCount();
86 return (n * (n - 1) / 2);
96 return createIndex(row, column);
101 return QModelIndex();
107 switch (
index.column())
110 if (role != Qt::DisplayRole)
116 return sourceModel()->headerData(src_index.row(), Qt::Horizontal, Qt::DisplayRole);
119 if (role != Qt::DisplayRole)
121 return sourceModel()->headerData(src_index.column(), Qt::Vertical, Qt::DisplayRole);
123 if (role != Qt::CheckStateRole)
129 return sourceModel()->data(src_index, Qt::CheckStateRole);
132 if (role != Qt::DisplayRole)
138 return sourceModel()->data(src_index, Qt::ToolTipRole);
147 return qobject_cast<CollisionMatrixModel*>(sourceModel())->reason(src_index);
154 if (role == Qt::CheckStateRole)
156 sourceModel()->setData(src_index, value, role);
158 Q_EMIT dataChanged(this->
index(r, 2), this->
index(r, 3));
166 for (
const auto idx : selection.indexes())
168 if (idx.column() != 2)
170 setData(idx, value ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
176 if (
index.column() == 2)
178 return Qt::ItemIsUserCheckable | QAbstractItemModel::flags(
index);
182 return QAbstractItemModel::flags(
index);
188 if (role != Qt::DisplayRole)
191 if (orientation == Qt::Horizontal)
202 return "Reason to Disable";
205 else if (orientation == Qt::Vertical)
214#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
215 connect(
this, SIGNAL(sourceModelChanged()),
this, SLOT(initSorting()));
219 sort_columns_ << 0 << 1;
220 sort_orders_ << Qt::AscendingOrder << Qt::AscendingOrder;
225 if (role == Qt::DisplayRole && orientation == Qt::Vertical)
231 return QSortFilterProxyModel::headerData(section, orientation, role);
240void SortFilterProxyModel::initSorting()
243 int prev_size = sort_columns_.size();
244 sort_columns_.resize(cols);
245 sort_orders_.resize(cols);
248 for (
int i = prev_size, end = sort_columns_.size(); i < end; ++i)
249 sort_columns_[i] = -1;
254 if (show_all_ == show_all)
257#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
261 show_all_ = show_all;
263#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
264 endFilterChange(QSortFilterProxyModel::Direction::Rows);
274 m->
data(m->
index(source_row, 2), Qt::CheckStateRole) != Qt::Checked)
277 const QRegularExpression regexp = filterRegularExpression();
278 if (regexp.pattern().isEmpty())
281 return m->
data(m->
index(source_row, 0, source_parent), Qt::DisplayRole).toString().contains(regexp) ||
282 m->
data(m->
index(source_row, 1, source_parent), Qt::DisplayRole).toString().contains(regexp);
288 if (left.userType() == QMetaType::Int)
290 return left.toInt() < right.toInt();
294 return left.toString() < right.toString();
300 int row_left = src_left.row();
301 int row_right = src_right.row();
302 QAbstractItemModel* m = sourceModel();
304 for (
int i = 0, end = sort_columns_.size(); i < end && sort_columns_[i] >= 0; ++i)
306 int sc = sort_columns_[i];
307 int role = sc == 2 ? Qt::CheckStateRole : Qt::DisplayRole;
308 QVariant value_left = m->data(m->index(row_left, sc), role);
309 QVariant value_right = m->data(m->index(row_right, sc), role);
311 if (value_left == value_right)
315 if (sort_orders_[i] == Qt::DescendingOrder)
332 int prev_idx = sort_columns_.indexOf(column);
334 prev_idx = sort_columns_.size() - 1;
336 sort_columns_.remove(prev_idx);
337 sort_orders_.remove(prev_idx);
339 sort_columns_.insert(0, column);
340 sort_orders_.insert(0, order);
342 QSortFilterProxyModel::sort(column, Qt::AscendingOrder);
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
DisabledReason reason(int row) const
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
CollisionLinearModel(CollisionMatrixModel *src, QObject *parent=nullptr)
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
int columnCount(const QModelIndex &parent) const override
int rowCount(const QModelIndex &parent) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
~CollisionLinearModel() override
void setEnabled(const QItemSelection &selection, bool value)
QVariant data(const QModelIndex &index, int role) const override
QModelIndex parent(const QModelIndex &child) const override
bool lessThan(const QModelIndex &src_left, const QModelIndex &src_right) const override
void setEnabled(const QItemSelection &selection, bool value)
SortFilterProxyModel(QObject *parent=nullptr)
void sort(int column, Qt::SortOrder order) override
void setShowAll(bool show_all)
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
DisabledReason
Reasons for disabling link pairs. Append "in collision" for understanding. NOT_DISABLED means the lin...
bool compareVariants(const QVariant &left, const QVariant &right)