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