1 #include "filtertreemodel.h"
2
3 #include "cardfilter.h"
4 #include "filtertree.h"
5
6 #include <QFont>
7
FilterTreeModel(QObject * parent)8 FilterTreeModel::FilterTreeModel(QObject *parent) : QAbstractItemModel(parent)
9 {
10 fTree = new FilterTree;
11 connect(fTree, SIGNAL(preInsertRow(const FilterTreeNode *, int)), this,
12 SLOT(proxyBeginInsertRow(const FilterTreeNode *, int)));
13 connect(fTree, SIGNAL(postInsertRow(const FilterTreeNode *, int)), this,
14 SLOT(proxyEndInsertRow(const FilterTreeNode *, int)));
15 connect(fTree, SIGNAL(preRemoveRow(const FilterTreeNode *, int)), this,
16 SLOT(proxyBeginRemoveRow(const FilterTreeNode *, int)));
17 connect(fTree, SIGNAL(postRemoveRow(const FilterTreeNode *, int)), this,
18 SLOT(proxyEndRemoveRow(const FilterTreeNode *, int)));
19 }
20
~FilterTreeModel()21 FilterTreeModel::~FilterTreeModel()
22 {
23 delete fTree;
24 }
25
proxyBeginInsertRow(const FilterTreeNode * node,int i)26 void FilterTreeModel::proxyBeginInsertRow(const FilterTreeNode *node, int i)
27 {
28 int idx;
29
30 idx = node->index();
31 if (idx >= 0)
32 beginInsertRows(createIndex(idx, 0, (void *)node), i, i);
33 }
34
proxyEndInsertRow(const FilterTreeNode * node,int)35 void FilterTreeModel::proxyEndInsertRow(const FilterTreeNode *node, int)
36 {
37 int idx;
38
39 idx = node->index();
40 if (idx >= 0)
41 endInsertRows();
42 }
43
proxyBeginRemoveRow(const FilterTreeNode * node,int i)44 void FilterTreeModel::proxyBeginRemoveRow(const FilterTreeNode *node, int i)
45 {
46 int idx;
47
48 idx = node->index();
49 if (idx >= 0)
50 beginRemoveRows(createIndex(idx, 0, (void *)node), i, i);
51 }
52
proxyEndRemoveRow(const FilterTreeNode * node,int)53 void FilterTreeModel::proxyEndRemoveRow(const FilterTreeNode *node, int)
54 {
55 int idx;
56
57 idx = node->index();
58 if (idx >= 0)
59 endRemoveRows();
60 }
61
indexToNode(const QModelIndex & idx) const62 FilterTreeNode *FilterTreeModel::indexToNode(const QModelIndex &idx) const
63 {
64 void *ip;
65 FilterTreeNode *node;
66
67 if (!idx.isValid())
68 return fTree;
69
70 ip = idx.internalPointer();
71 if (ip == NULL)
72 return fTree;
73
74 node = static_cast<FilterTreeNode *>(ip);
75 return node;
76 }
77
addFilter(const CardFilter * f)78 void FilterTreeModel::addFilter(const CardFilter *f)
79 {
80 emit layoutAboutToBeChanged();
81 fTree->termNode(f);
82 emit layoutChanged();
83 }
84
rowCount(const QModelIndex & parent) const85 int FilterTreeModel::rowCount(const QModelIndex &parent) const
86 {
87 const FilterTreeNode *node;
88 int result;
89
90 if (parent.column() > 0)
91 return 0;
92
93 node = indexToNode(parent);
94 if (node)
95 result = node->childCount();
96 else
97 result = 0;
98
99 return result;
100 }
101
columnCount(const QModelIndex &) const102 int FilterTreeModel::columnCount(const QModelIndex & /*parent*/) const
103 {
104 return 1;
105 }
106
data(const QModelIndex & index,int role) const107 QVariant FilterTreeModel::data(const QModelIndex &index, int role) const
108 {
109 const FilterTreeNode *node;
110
111 if (!index.isValid())
112 return QVariant();
113 if (index.column() >= columnCount())
114 return QVariant();
115
116 node = indexToNode(index);
117 if (node == NULL)
118 return QVariant();
119
120 switch (role) {
121 case Qt::FontRole:
122 if (!node->isLeaf()) {
123 QFont f;
124 f.setBold(true);
125 return f;
126 }
127 break;
128 case Qt::DisplayRole:
129 case Qt::EditRole:
130 case Qt::ToolTipRole:
131 case Qt::StatusTipRole:
132 case Qt::WhatsThisRole:
133 return node->text();
134 case Qt::CheckStateRole:
135 if (node->isEnabled())
136 return Qt::Checked;
137 else
138 return Qt::Unchecked;
139 default:
140 return QVariant();
141 }
142
143 return QVariant();
144 }
145
setData(const QModelIndex & index,const QVariant & value,int role)146 bool FilterTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
147 {
148 FilterTreeNode *node;
149
150 if (!index.isValid())
151 return false;
152 if (index.column() >= columnCount())
153 return false;
154 if (role != Qt::CheckStateRole)
155 return false;
156
157 node = indexToNode(index);
158 if (node == NULL || node == fTree)
159 return false;
160
161 Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
162 if (state == Qt::Checked)
163 node->enable();
164 else
165 node->disable();
166
167 emit dataChanged(index, index);
168 return true;
169 }
170
flags(const QModelIndex & index) const171 Qt::ItemFlags FilterTreeModel::flags(const QModelIndex &index) const
172 {
173 const FilterTreeNode *node;
174 Qt::ItemFlags result;
175
176 if (!index.isValid())
177 return Qt::NoItemFlags;
178
179 node = indexToNode(index);
180 if (node == NULL)
181 return Qt::NoItemFlags;
182
183 result = Qt::ItemIsEnabled;
184 if (node == fTree)
185 return result;
186
187 result |= Qt::ItemIsSelectable;
188 result |= Qt::ItemIsUserCheckable;
189
190 return result;
191 }
192
nodeIndex(const FilterTreeNode * node,int row,int column) const193 QModelIndex FilterTreeModel::nodeIndex(const FilterTreeNode *node, int row, int column) const
194 {
195 FilterTreeNode *child;
196
197 if (column > 0 || row >= node->childCount())
198 return QModelIndex();
199
200 child = node->nodeAt(row);
201 return createIndex(row, column, child);
202 }
203
index(int row,int column,const QModelIndex & parent) const204 QModelIndex FilterTreeModel::index(int row, int column, const QModelIndex &parent) const
205 {
206 const FilterTreeNode *node;
207
208 if (!hasIndex(row, column, parent))
209 return QModelIndex();
210
211 node = indexToNode(parent);
212 if (node == NULL)
213 return QModelIndex();
214
215 return nodeIndex(node, row, column);
216 }
217
parent(const QModelIndex & ind) const218 QModelIndex FilterTreeModel::parent(const QModelIndex &ind) const
219 {
220 const FilterTreeNode *node;
221 FilterTreeNode *parent;
222 QModelIndex idx;
223
224 if (!ind.isValid())
225 return QModelIndex();
226
227 node = indexToNode(ind);
228 if (node == NULL || node == fTree)
229 return QModelIndex();
230
231 parent = node->parent();
232 if (parent) {
233 int row = parent->index();
234 if (row < 0)
235 return QModelIndex();
236 idx = createIndex(row, 0, parent);
237 return idx;
238 }
239
240 return QModelIndex();
241 }
242
removeRows(int row,int count,const QModelIndex & parent)243 bool FilterTreeModel::removeRows(int row, int count, const QModelIndex &parent)
244 {
245 FilterTreeNode *node;
246 int i, last;
247
248 last = row + count - 1;
249 if (!parent.isValid() || count < 1 || row < 0)
250 return false;
251
252 node = indexToNode(parent);
253 if (node == NULL || last >= node->childCount())
254 return false;
255
256 for (i = 0; i < count; i++)
257 node->deleteAt(row);
258
259 if (node != fTree && node->childCount() < 1)
260 return removeRow(parent.row(), parent.parent());
261
262 return true;
263 }
264