]> git.sven.stormbind.net Git - sven/vym.git/blob - taskmodel.cpp
65b2f27adcbbdccc212f20214ed9e67a00aaf310
[sven/vym.git] / taskmodel.cpp
1 #include "taskmodel.h"
2
3 #include <QDebug>
4
5 #include "branchitem.h"
6 #include "branchobj.h"
7 #include "task.h"
8 #include "vymmodel.h"
9
10 TaskModel::TaskModel(QObject *parent)
11     : QAbstractTableModel(parent)
12 {
13     showParentsLevel = 0;
14 }
15
16 QModelIndex TaskModel::index (Task* t)
17 {
18     int n=tasks.indexOf (t);
19     if (n<0)
20         return QModelIndex();
21     else    
22         return createIndex (n,0,t);
23 }
24
25 QModelIndex TaskModel::indexRowEnd (Task* t)
26 {
27     int n=tasks.indexOf (t);
28     if (n<0)
29         return QModelIndex();
30     else    
31         return createIndex (n,6,t);
32 }
33
34 Task* TaskModel::getTask (const QModelIndex &ix) const
35 {
36     if (ix.isValid() )
37         return tasks.at (ix.row() );
38     else
39         return NULL;
40 }
41
42 int TaskModel::rowCount(const QModelIndex &parent) const
43 {
44     Q_UNUSED(parent);
45     return tasks.size();
46 }
47
48 int TaskModel::columnCount(const QModelIndex &parent) const
49 {
50     Q_UNUSED(parent);
51     return 7;
52 }
53
54 QVariant TaskModel::data(const QModelIndex &index, int role) const
55 {
56     if (!index.isValid())
57         return QVariant();
58     
59     if (index.row() >= tasks.size() || index.row() < 0)
60         return QVariant();
61
62     BranchItem *bi=tasks.at(index.row())->getBranch();
63     Task *t=tasks.at(index.row() );
64
65     if (role == Qt::DisplayRole) 
66     {
67         if (index.column() == 0)
68             return t->getPriority();
69         else if (index.column() == 1)
70             return t->getStatusString() + " - " +t->getAwakeString();
71         else if (index.column() == 2)
72             return t->getAgeCreation();
73         else if (index.column() == 3)
74             return t->getAgeModified();
75         else if (index.column() == 4)
76             return t->getDaysSleep();
77         else if (index.column() == 5)
78         {
79             QString s = bi->getModel()->getMapName();
80             if (s.isEmpty() )
81                 return "-";    
82             else
83                 return bi->getModel()->getMapName();
84         }
85         else if (index.column() == 6)
86         {
87             BranchItem *bi = tasks.at(index.row())->getBranch();
88             return bi->getHeadingPlainWithParents( showParentsLevel );
89         }
90     } else if (role == Qt::DecorationRole && index.column() == 1)
91     {
92         return QIcon(":/flag-" + t->getIconString() + ".png");
93     }
94     else // role != Qt::DisplayRole
95     {
96         if (role == Qt::ForegroundRole && bi ) 
97             return bi->getHeadingColor();
98         if (role == Qt::BackgroundRole && bi ) 
99         {
100             BranchItem *frameBI=bi->getFramedParentBranch(bi);
101             if (frameBI && index.column() != 5)
102             {
103                 BranchObj *bo=frameBI->getBranchObj();
104                 if (bo) 
105                     // Return frame background
106                     return bo->getFrameBrushColor();
107             }
108             else
109             {
110                 // Return map background
111                 return bi->getModel()->getMapBackgroundColor();
112             }
113         }
114     }   
115
116     return QVariant();
117 }
118
119 QVariant TaskModel::headerData(int section, Qt::Orientation orientation, int role) const
120 {
121     if (role != Qt::DisplayRole)
122         return QVariant();
123
124     if (orientation == Qt::Horizontal) {
125         switch (section) {
126             case 0:
127                 return tr("Prio","TaskEditor");
128             case 1:
129                 return tr("Status","TaskEditor");
130             case 2:
131                 return tr("Age total","TaskEditor");
132             case 3:
133                 return tr("Age mod.","TaskEditor");
134             case 4:
135                 return tr("Sleep","TaskEditor");
136             case 5:
137                 return tr("Map","TaskEditor");
138             case 6:
139                 return tr("Task","TaskEditor");
140             default:
141                 return QVariant();
142         }
143     }
144     return QVariant();
145 }
146
147 bool TaskModel::insertRows(int position, int rows, const QModelIndex &index, Task* t)
148 {
149     Q_UNUSED(index);
150     beginInsertRows(QModelIndex(), position, position+rows-1);
151
152     for (int row=0; row < rows; row++) 
153         tasks.insert(position, t);
154
155     endInsertRows();
156     return true;
157 }
158
159 bool TaskModel::removeRows(int position, int rows, const QModelIndex &index)
160 {
161     Q_UNUSED(index);
162     beginRemoveRows(QModelIndex(), position, position+rows-1);
163
164     for (int row=0; row < rows; ++row) 
165         delete (tasks.takeAt(position)) ;
166
167     endRemoveRows();
168     return true;
169 }
170
171 bool TaskModel::setData(const QModelIndex &index, Task* t, int role)
172 {
173     if (index.isValid() && role == Qt::EditRole) 
174     {
175         int row = index.row();
176
177         tasks.replace(row, t);
178         emit(dataChanged(index, index));
179
180         return true;
181     }
182
183     return false;
184 }
185
186 void TaskModel::emitDataChanged (Task* t)
187 {
188     QModelIndex ix=index (t);
189     if (ix.isValid() )
190     {
191         int row=ix.row();
192         int col=0;
193         while (col<columnCount(QModelIndex() ) )
194         {
195             ix=createIndex (row, col, t);
196             if (ix.isValid() ) emit(dataChanged(ix,ix) );
197             col++;  
198         }    
199     }
200 }
201
202 Qt::ItemFlags TaskModel::flags(const QModelIndex &index) const
203 {
204     if (!index.isValid())
205         return Qt::ItemIsEnabled;
206
207     return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
208 }
209
210 int TaskModel::count (VymModel *model)
211 {
212     if (!model) return tasks.size();
213     int n=0;
214     foreach (Task *t,tasks) if (t->getBranch()->getModel()==model) n++;
215     return n;
216 }
217
218 Task* TaskModel::createTask (BranchItem *bi)
219 {
220     if (bi)
221     {
222         foreach (Task* t, tasks)
223         {
224             if (t->getBranch()==bi)
225             {
226                 qWarning()<<"TaskModel::createTask Branch exists already!";
227                 return NULL;
228             }
229         }
230         Task* task=new Task(this);
231         task->setBranch (bi);
232         task->setAwake(Task::Morning);
233         insertRows(tasks.count(), 1, QModelIndex(),task);
234
235         bi->setTask (task);
236
237         return task;
238     }
239     qWarning()<<"TaskEditor::addItem - item exists";
240     return NULL;
241 }
242
243 void TaskModel::deleteTask (Task* t)
244 {
245     int pos=tasks.indexOf(t);
246     if (pos>=0)
247         removeRows(pos, 1,QModelIndex() );
248 }
249
250 void TaskModel::recalcPriorities() 
251 {
252     emit (layoutAboutToBeChanged() );
253     int minPrio=1000000;
254     foreach (Task *t,tasks)
255     {   
256         int p=0;
257         BranchItem *bi=t->getBranch();
258
259         // Status
260         switch (t->getStatus() )
261         {
262             case Task::NotStarted: break;
263             case Task::WIP: p+=10; break;
264             case Task::Finished: p+=2000; break;
265         }
266
267         // Awake and sleeping
268         switch (t->getAwake() )
269         {
270             case Task::Morning: p-=1000; break;
271             case Task::WideAwake: break;
272             case Task::Sleeping: p+=1000 + t->getDaysSleep(); break;
273         }
274
275         // Color (importance)
276         QColor c = bi->getHeadingColor();
277
278         // light blueish green
279         if (c == QColor ("#00aa7f") ) p -= 20;
280
281         // green (e.g. from vym < 2.6.3 with #005500)
282         if (c.red() == 0 && c.blue() == 0 && c.green() < 160) p -= 40;
283
284         // orange
285         if (c == QColor ("#d95100") ) p -= 60;
286
287         // red
288         if (c == QColor ("#ff0000") ) p -= 80;
289
290         // Flags
291         if (bi->hasActiveStandardFlag ("stopsign") ) p-=800;
292
293         // Age
294         p-=t->getAgeModified();
295         p-=t->getAgeCreation() * 1.0 / 365 * 80; // After a year, this is as important as "red"
296
297         // Position in subtree
298         p += bi->num();
299
300         t->setPriority (p);
301         if (p<minPrio) minPrio=p;
302     }
303     // Normalize, so that most important task has prio 1
304     foreach (Task *t,tasks)
305     {   
306         t->setPriority (1-  minPrio + t->getPriority() );
307         //emitDataChanged (t);
308     }
309
310     emit (layoutChanged() );
311 }
312
313 void TaskModel::setShowParentsLevel(uint i)
314 {
315     showParentsLevel = i;
316     recalcPriorities(); // Triggers update of view
317 }
318
319 uint TaskModel::getShowParentsLevel()
320 {
321     return showParentsLevel;
322 }
323