/** * @file CandidateKeyFilter.cpp * @brief Implementation of CandidateKeyFilter */ #include "CandidateKeyFilter.h" #include "JS8_Include/pimpl_impl.h" #include #include class CandidateKeyFilter::impl final { public: explicit impl(int referenced_key_column, int referenced_key_role, QAbstractItemModel const *referencing_model, int referencing_key_column, int referencing_key_role) : referencing_{referencing_model}, referencing_key_column_{referencing_key_column}, referencing_key_role_{referencing_key_role}, referenced_key_column_{referenced_key_column}, referenced_key_role_{referenced_key_role} {} QAbstractItemModel const *referencing_; int referencing_key_column_; int referencing_key_role_; int referenced_key_column_; int referenced_key_role_; QModelIndex active_key_; }; CandidateKeyFilter::CandidateKeyFilter(QAbstractItemModel *referenced_model, int referenced_key_column, QObject *parent, int referenced_key_role) : QSortFilterProxyModel{parent}, m_{referenced_key_column, referenced_key_role, nullptr, 0, Qt::EditRole} { setSourceModel(referenced_model); } CandidateKeyFilter::CandidateKeyFilter( QAbstractItemModel *referenced_model, QAbstractItemModel const *referencing_model, int referenced_key_column, int referencing_key_column, QObject *parent, int referenced_key_role, int referencing_key_role) : QSortFilterProxyModel{parent}, m_{referenced_key_column, referenced_key_role, referencing_model, referencing_key_column, referencing_key_role} { setSourceModel(referenced_model); } CandidateKeyFilter::~CandidateKeyFilter() {} void CandidateKeyFilter::set_active_key(QModelIndex const &index) { if (m_->referencing_) { beginFilterChange(); if (index.isValid()) { Q_ASSERT(index.column() == m_->referencing_key_column_); m_->active_key_ = index; } endFilterChange(); } } bool CandidateKeyFilter::filterAcceptsRow( int candidate_row, QModelIndex const &candidate_parent) const { if (!m_->referencing_) // many to many passes all { return true; } auto candidate_key = sourceModel() ->index(candidate_row, m_->referenced_key_column_, candidate_parent) .data(m_->referenced_key_role_); // Include the current key. if (m_->active_key_.isValid() && candidate_key == m_->active_key_.data(m_->referencing_key_role_)) { return true; } // Filter out any candidates already in the referencing key rows. return m_->referencing_ ->match(m_->referencing_->index(0, m_->referencing_key_column_), m_->referencing_key_role_, candidate_key, 1, Qt::MatchExactly) .isEmpty(); }