Unity 8
unitysortfilterproxymodelqml.cpp
1 /*
2  * Copyright (C) 2012 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 // self
18 #include "unitysortfilterproxymodelqml.h"
19 
20 // Qt
21 #include <QDebug>
22 
23 UnitySortFilterProxyModelQML::UnitySortFilterProxyModelQML(QObject *parent)
24  : QSortFilterProxyModel(parent)
25  , m_invertMatch(false)
26 {
27  connect(this, &UnitySortFilterProxyModelQML::modelReset, this, &UnitySortFilterProxyModelQML::countChanged);
28  connect(this, &UnitySortFilterProxyModelQML::rowsInserted, this, &UnitySortFilterProxyModelQML::countChanged);
29  connect(this, &UnitySortFilterProxyModelQML::rowsRemoved, this, &UnitySortFilterProxyModelQML::countChanged);
30 }
31 
32 /*
33  * Enter row index of filtered/sorted model, returns row index of source model
34  */
35 int UnitySortFilterProxyModelQML::mapRowToSource(int row)
36 {
37  if (sourceModel() == nullptr)
38  return -1;
39 
40  return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
41 }
42 
43 QHash<int, QByteArray> UnitySortFilterProxyModelQML::roleNames() const
44 {
45  return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
46 }
47 
48 void
49 UnitySortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
50 {
51  if (itemModel == nullptr) {
52  return;
53  }
54 
55  if (itemModel != sourceModel()) {
56  if (sourceModel() != nullptr) {
57  sourceModel()->disconnect(this);
58  }
59 
60  setSourceModel(itemModel);
61 
62  connect(itemModel, &QAbstractItemModel::modelReset, this, &UnitySortFilterProxyModelQML::totalCountChanged);
63  connect(itemModel, &QAbstractItemModel::rowsInserted, this, &UnitySortFilterProxyModelQML::totalCountChanged);
64  connect(itemModel, &QAbstractItemModel::rowsRemoved, this, &UnitySortFilterProxyModelQML::totalCountChanged);
65 
66  Q_EMIT totalCountChanged();
67  Q_EMIT modelChanged();
68  }
69 }
70 
71 QVariantMap
72 UnitySortFilterProxyModelQML::get(int row)
73 {
74  QVariantMap res;
75  const QHash<int, QByteArray> roles = roleNames();
76  auto it = roles.begin();
77  for ( ; it != roles.end(); ++it) {
78  res[*it] = data(row, it.key());
79  }
80  return res;
81 }
82 
83 QVariant
84 UnitySortFilterProxyModelQML::data(int row, int role)
85 {
86  if (sourceModel() == nullptr) {
87  return QVariant();
88  }
89 
90  return index(row, 0).data(role);
91 }
92 
93 int
94 UnitySortFilterProxyModelQML::totalCount() const
95 {
96  if (sourceModel() != nullptr) {
97  return sourceModel()->rowCount();
98  } else {
99  return 0;
100  }
101 }
102 
103 int
104 UnitySortFilterProxyModelQML::count()
105 {
106  return rowCount();
107 }
108 
109 bool
110 UnitySortFilterProxyModelQML::invertMatch() const
111 {
112  return m_invertMatch;
113 }
114 
115 void
116 UnitySortFilterProxyModelQML::setInvertMatch(bool invertMatch)
117 {
118  if (invertMatch != m_invertMatch) {
119  m_invertMatch = invertMatch;
120  Q_EMIT invertMatchChanged(invertMatch);
121  invalidateFilter();
122  }
123 }
124 
125 bool
126 UnitySortFilterProxyModelQML::filterAcceptsRow(int sourceRow,
127  const QModelIndex &sourceParent) const
128 {
129  // If there's no regexp set, always accept all rows indepenently of the invertMatch setting
130  if (filterRegExp().isEmpty()) {
131  return true;
132  }
133 
134  bool result = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
135  return (m_invertMatch) ? !result : result;
136 }
137 
138 int
139 UnitySortFilterProxyModelQML::findFirst(int role, const QVariant& value) const
140 {
141  QModelIndexList matches = match(index(0, 0), role, value, 1, Qt::MatchExactly);
142  if (!matches.isEmpty()) {
143  return matches.first().row();
144  } else {
145  return -1;
146  }
147 }
148 
149 int
150 UnitySortFilterProxyModelQML::mapFromSource(int row)
151 {
152  if (sourceModel() != nullptr) {
153  return QSortFilterProxyModel::mapFromSource(sourceModel()->index(row, 0)).row();
154  } else {
155  return -1;
156  }
157 }
158 
159 int
160 UnitySortFilterProxyModelQML::mapToSource(int row)
161 {
162  if (sourceModel() != nullptr) {
163  return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
164  } else {
165  return -1;
166  }
167 }