Skip to content

Instantly share code, notes, and snippets.

@mindon
Last active November 24, 2023 02:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindon/a2a0432c9ede07b627f62af94ac95a96 to your computer and use it in GitHub Desktop.
Save mindon/a2a0432c9ede07b627f62af94ac95a96 to your computer and use it in GitHub Desktop.
Qt Multi-Columns QSortFilterProxyModel: MixedFilterModel
#include "MixedFilterModel.h"
bool MixedFilterModel::fit(QString s, QVariant rule)
{
int metaTypeId = rule.metaType().id();
if (metaTypeId == QMetaType::QString) {
QString r = rule.toString();
if (r == "*")
return true;
if (r.contains("*")) {
QString mr = QRegularExpression::wildcardToRegularExpression(r);
QRegularExpression re(QRegularExpression::anchoredPattern(mr), QRegularExpression::CaseInsensitiveOption);
return re.match(s).hasMatch();
}
return s.contains(r, Qt::CaseInsensitive);
}
if (metaTypeId == QMetaType::QRegularExpression) {
return rule.toRegularExpression().match(s).hasMatch();
}
if (rule.userType() == qMetaTypeId<QList<QVariant>>()) {
foreach (QVariant part, rule.toList()) {
if (MixedFilterModel::fit(s, part))
return true;
}
}
return false;
}
MixedFilterModel::MixedFilterModel(QObject* parent)
: QSortFilterProxyModel(parent)
{
//
}
MixedFilterModel::MixedFilterModel(QList<int> x, QObject* parent)
: QSortFilterProxyModel(parent)
, exclusived(x)
{
}
MixedFilterModel::MixedFilterModel(QAbstractItemModel* sourceModel, QObject* parent)
: QSortFilterProxyModel(parent)
{
setSourceModel(sourceModel);
}
MixedFilterModel::MixedFilterModel(QAbstractItemModel* sourceModel, QList<int> x, QObject* parent)
: QSortFilterProxyModel(parent)
, exclusived(x)
{
setSourceModel(sourceModel);
}
bool MixedFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
if (rules.isEmpty())
return true;
for (QMap<int, QVariant>::const_iterator it = rules.begin();
it != rules.end();
++it) {
int col = it.key();
QModelIndex idx = sourceModel()->index(sourceRow, col, sourceParent);
if (!idx.isValid() || idx.data().isNull()) {
return false;
}
QString s = idx.data().toString();
QVariant d = it.value();
if (!MixedFilterModel::fit(s, d))
return false;
}
return true;
}
void MixedFilterModel::find(QMap<int, QVariant> _rules)
{
rules = _rules;
invalidateRowsFilter();
}
void MixedFilterModel::find(int col, QVariant rule)
{
if (exclusived.contains(col)) {
foreach (int x, exclusived) {
if (x == col || rules.find(x) == rules.end())
continue;
rules.remove(x);
}
}
rules[col] = rule;
invalidateRowsFilter();
}
void MixedFilterModel::reset()
{
rules.clear();
invalidateRowsFilter();
}
void MixedFilterModel::reset(int col)
{
if (rules.find(col) != rules.end()) {
rules.remove(col);
}
invalidateRowsFilter();
}
void MixedFilterModel::reset(QList<int> cols)
{
foreach (int col, cols) {
if (rules.find(col) != rules.end()) {
rules.remove(col);
}
}
invalidateRowsFilter();
}
void MixedFilterModel::setExclusived(QList<int> x)
{
exclusived = x;
}
#pragma once
#ifndef MIXED_FILTER_MODEL_H
#define MIXED_FILTER_MODEL_H
#include <QSortFilterProxyModel>
#include <QMap>
#include <QMetaType>
class MixedFilterModel: public QSortFilterProxyModel {
public:
static bool fit(QString s, QVariant rule);
explicit MixedFilterModel(QObject *parent = nullptr);
MixedFilterModel(QList<int> x, QObject *parent = nullptr);
MixedFilterModel(QAbstractItemModel *sourceModel, QObject *parent = nullptr);
MixedFilterModel(QAbstractItemModel *sourceModel, QList<int> x, QObject *parent = nullptr);
void find(QMap<int, QVariant> rules);
void find(int col, QVariant rule);
void reset(int col);
void reset(QList<int> cols);
void reset();
void setExclusived(QList<int>);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private:
QMap<int, QVariant> rules;
QList<int> exclusived;
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment