]> git.sven.stormbind.net Git - sven/vym.git/blob - src/treemodel.cpp
Replace Pierre as the maintainer
[sven/vym.git] / src / treemodel.cpp
1 #include <QtGui>
2
3 #include "attributeitem.h"
4 #include "branchitem.h"
5 #include "branchobj.h"
6 #include "imageitem.h"
7 #include "treeitem.h"
8 #include "treemodel.h"
9 #include "xlinkitem.h"
10
11 TreeModel::TreeModel(QObject *parent) : QAbstractItemModel(parent)
12 {
13     // qDebug()<<"Constr TreeModel  this=" << this;
14     QList<QVariant> rootData;
15     rootData << "Heading";
16     // rootData << "Type";
17     rootItem = new BranchItem();
18 }
19
20 TreeModel::~TreeModel()
21 {
22     // qDebug()<<"Destr TreeModel  this="<<this;
23     delete rootItem;
24 }
25
26 QVariant TreeModel::data(const QModelIndex &index, int role) const
27 {
28     if (!index.isValid())
29         return QVariant();
30
31     TreeItem *item = getItem(index);
32     BranchItem *bi = nullptr;
33     if (item->isBranchLikeType())
34         bi = (BranchItem*)item;
35
36     if (role == Qt::EditRole || role == Qt::DisplayRole)
37         return item->data(index.column());
38
39     if (role == Qt::ForegroundRole)
40         return item->getHeadingColor();
41
42     if (role == Qt::BackgroundRole) {
43         if (bi) {
44             BranchItem *frameBI = bi->getFramedParentBranch(bi);
45             if (frameBI && index.column() != 5) {
46                 BranchObj *bo = frameBI->getBranchObj();
47                 if (bo)
48                     return bo->getFrameBrushColor();
49             }
50             else
51                 return backgroundColor;
52         }
53     }
54
55     return QVariant();
56 }
57
58 Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
59 {
60     if (!index.isValid())
61         return Qt::NoItemFlags;
62
63     return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
64 }
65
66 QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
67                                int role) const
68 {
69     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
70         return rootItem->data(section);
71
72     return QVariant();
73 }
74
75 QModelIndex TreeModel::index(TreeItem *ti)
76 {
77     if (!ti->parent())
78         return QModelIndex();
79     else
80         return createIndex(ti->row(), 0, ti);
81 }
82
83 QModelIndex TreeModel::index(int row, int column,
84                              const QModelIndex &parent) const
85 {
86     // Make sure to return invalid index for invalid values (see modeltest)
87     if (row < 0 || column < 0)
88         return QModelIndex();
89     if (column != 0)
90         return QModelIndex();
91
92     TreeItem *parentItem;
93
94     if (!parent.isValid())
95         parentItem = rootItem;
96     else
97         parentItem = getItem(parent);
98
99     TreeItem *childItem = parentItem->child(row);
100     if (childItem)
101         return createIndex(row, column, childItem);
102     else
103         return QModelIndex();
104 }
105
106 QModelIndex TreeModel::parent(const QModelIndex &index) const
107 {
108     if (!index.isValid())
109         return QModelIndex();
110
111     TreeItem *ti = getItem(index);
112     TreeItem *parentItem = ti->parent();
113     if (parentItem == rootItem)
114         return QModelIndex();
115     return createIndex(parentItem->childNumber(), 0, parentItem);
116 }
117
118 int TreeModel::rowCount(const QModelIndex &parent) const
119 {
120     TreeItem *parentItem;
121
122     if (!parent.isValid())
123         parentItem = rootItem;
124     else
125         parentItem = getItem(parent);
126
127     return parentItem->childCount();
128 }
129
130 int TreeModel::columnCount(const QModelIndex &parent) const
131 {
132     int c;
133     if (parent.isValid())
134         c = getItem(parent)->columnCount();
135     else
136         c = rootItem->columnCount();
137     return c;
138 }
139
140 void TreeModel::nextBranch(BranchItem *&current, BranchItem *&previous,
141                            bool deepLevelsFirst, BranchItem *start)
142 {
143     if (deepLevelsFirst) {
144         // Walk through map beginning at current with previous==0
145         // Start at root, if current==NULL
146         if (!current) {
147             if (start) {
148                 current = start;
149                 previous = current->parentBranch();
150             }
151             else {
152                 previous = (BranchItem *)rootItem;
153                 current = previous->getFirstBranch();
154                 return;
155             }
156         }
157
158         // Walk the tree by always turning "left"
159         // and returning an element when going up
160         if (current == previous) {
161             // Had leaf before, go up again.
162             if (start && start == current) {
163                 current = NULL;
164                 return;
165             }
166             current = current->parentBranch();
167             if (!current)
168                 return;
169             return nextBranch(current, previous, deepLevelsFirst, start);
170         }
171
172         if (current->depth() > previous->depth()) {
173             // Coming from above, try to go deeper
174             if (current->branchCount() > 0) {
175                 // Turn "left" and go deeper
176                 previous = current;
177                 current = current->getFirstBranch();
178                 return nextBranch(current, previous, deepLevelsFirst);
179             }
180             else {
181                 // turn around and go up again
182                 previous = current;
183                 return;
184             }
185         }
186         else {
187             // Coming from below, try to go down again to siblings
188
189             BranchItem *sibling = current->getBranchNum(previous->num() + 1);
190             if (sibling) {
191                 // Found sibling of previous, go there
192                 previous = current;
193                 current = sibling;
194                 return nextBranch(current, previous, deepLevelsFirst, start);
195             }
196             else {
197                 // and go further up
198                 if (current == rootItem)
199                     current = NULL;
200                 previous = current;
201                 return;
202             }
203         }
204     }
205     else {
206         // Walk through map beginning at current with previous==0
207         // Start at root, if current==NULL
208         if (!current) {
209             if (start) {
210                 current = start;
211                 previous = (BranchItem *)(start->parent());
212                 return;
213             }
214             else {
215                 previous = (BranchItem *)rootItem;
216                 current = previous->getFirstBranch();
217                 return;
218             }
219         }
220
221         if (current->depth() > previous->depth()) {
222             // Going deeper
223             if (current->branchCount() > 0) {
224                 // Turn "left" and go deeper
225                 previous = current;
226                 current = current->getFirstBranch();
227                 return;
228             }
229             else {
230                 // turn around and go up again
231                 previous = current;
232                 nextBranch(current, previous, deepLevelsFirst, start);
233                 return;
234             }
235         }
236         else {
237             if (start && previous == start) {
238                 current = NULL;
239                 return;
240             }
241
242             BranchItem *sibling = current->getBranchNum(previous->num() + 1);
243             if (sibling) {
244                 // Found sibling of previous, go there
245                 previous = current;
246                 current = sibling;
247                 return;
248             }
249             else {
250                 // no sibling, go further up left
251                 previous = current;
252                 current = current->parentBranch();
253                 if (!current) {
254                     current = NULL;
255                     return;
256                 }
257                 else {
258                     nextBranch(current, previous, deepLevelsFirst, start);
259                 }
260             }
261             return;
262         }
263     }
264 }
265
266 bool TreeModel::removeRows(int row, int count, const QModelIndex &parent)
267 {
268     int last = row + count - 1;
269     TreeItem *pi;
270     if (parent.isValid())
271         pi = getItem(parent);
272     else
273         pi = rootItem;
274     TreeItem *ti;
275
276     for (int i = row; i <= last; i++) {
277         ti = pi->getChildNum(row);
278         pi->removeChild(row); // does not delete object!
279         delete ti;
280     }
281     return true;
282 }
283
284 TreeItem *TreeModel::getItem(const QModelIndex &index) const
285 {
286     if (index.isValid()) {
287         TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
288         if (item)
289             return item;
290     }
291     return NULL;
292 }
293
294 BranchItem *TreeModel::getRootItem() { return rootItem; }
295
296 int TreeModel::xlinkCount() { return xlinks.count(); }
297
298 Link *TreeModel::getXLinkNum(const int &n)
299 {
300     if (n >= 0 && n < xlinks.count())
301         return xlinks.at(n);
302     else
303         return NULL;
304 }