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