File: CandidateKeyFilter.cpp

package info (click to toggle)
js8call 2.5.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,720 kB
  • sloc: cpp: 562,655; sh: 898; python: 132; ansic: 102; makefile: 4
file content (81 lines) | stat: -rw-r--r-- 2,847 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "CandidateKeyFilter.h"

#include <QAbstractItemModel>
#include <QModelIndex>

#include "JS8_Include/pimpl_impl.h"

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_) {
        if (index.isValid()) {
            Q_ASSERT(index.column() == m_->referencing_key_column_);
            m_->active_key_ = index;
        }
        invalidateFilter();
    }
}

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();
}