Added edit score functionality
[scorecard] / src / table-model.cpp
1
2 #include <QColor>
3 #include <QBrush>
4 #include <QFont>
5 #include "table-model.h"
6
7 Qt::ItemFlags ScoreTableModel::flags ( const QModelIndex & index )
8 {
9   Qt::ItemFlags flags = QAbstractItemModel::flags(index);
10   qDebug() << "flags " << currentMode;
11   
12   return flags;
13 }
14
15 void ScoreTableModel::setMode(int m)
16 {
17   currentMode = m;
18 }
19
20 int ScoreTableModel::mode(void)
21 {
22   return currentMode;
23 }
24
25 // Assign the 'sList' to internal 'scoreList'. Set the current score
26 // to 'currentScore', or to 's'.
27 void ScoreTableModel::setScore(QList<Score *> &sList, Score *s)
28 {
29   scoreList = sList;
30   if (scoreList.size() > 0) {
31     if (s) {
32       currentScore = scoreList.indexOf(s);
33       if (currentScore == -1)
34         currentScore = 0;
35     }
36     score = scoreList.at(currentScore); // NOTE: assumes non-empty list
37   }
38 }
39
40 void ScoreTableModel::setClub(QList<Club *> &cList)
41 {
42   clubList = cList;
43
44   if (clubList.size() > 0)
45     club = clubList.at(0);
46
47   if (club)
48     course = club->getCourse(0);
49 }
50
51 QString ScoreTableModel::getInfoText()
52 {
53   QString str("");
54
55   if (score)
56     str = QString("%1, %2 / [%3/%4]").arg(score->getCourseName()).arg(score->getDate()).arg(currentScore+1).arg(scoreList.count());
57
58   return str;
59 }
60
61 QString ScoreTableModel::getCountText()
62 {
63   QString str = QString("%1/%2").arg(currentScore+1, 2).arg(scoreList.count(), 2);
64   return str;
65 }
66
67 QString& ScoreTableModel::clubName(void)
68 {
69   QString str("");
70
71   if (club)
72     str = club->getName();
73
74   return str;
75 }
76
77 QString& ScoreTableModel::courseName(void)
78 {
79   QString str("");
80
81   if (course)
82     str = course->getName();
83
84   return str;
85 }
86
87 Course *ScoreTableModel::findCourse(const QString &clubName, 
88                                     const QString &courseName)
89 {
90   QListIterator<Club *> i(clubList);
91   Club *c;
92
93   while (i.hasNext()) {
94     c = i.next();
95     if (c->getName() == clubName) {
96       return c->getCourse(courseName);
97     }
98   }
99   return 0;
100 }
101
102 Club *ScoreTableModel::getClub(void)
103 {
104   return club;
105 }
106
107 Course *ScoreTableModel::getCourse(void)
108 {
109   return course;
110 }
111
112 Score *ScoreTableModel::getScore(void)
113 {
114   return score;
115 }
116
117 void ScoreTableModel::first()
118 {
119   if (score && course) {
120     currentScore = 0;
121     score = scoreList.at(currentScore);
122     course = findCourse(score->getClubName(), score->getCourseName());
123     emit dataChanged(createIndex(0, 0), createIndex(ROW_COUNT-1, COL_COUNT-1));
124   }
125 }
126
127 void ScoreTableModel::last()
128 {
129   if (score && course) {
130     currentScore = scoreList.size() - 1;
131     score = scoreList.at(currentScore);
132     course = findCourse(score->getClubName(), score->getCourseName());
133     emit dataChanged(createIndex(0, 0), createIndex(ROW_COUNT-1, COL_COUNT-1));
134   }
135 }
136
137 void ScoreTableModel::next()
138 {
139   if (score && course) {
140     if (currentScore < (scoreList.size() - 1)) {
141       currentScore++;
142       score = scoreList.at(currentScore);
143       course = findCourse(score->getClubName(), score->getCourseName());
144       emit dataChanged(createIndex(0, 0), createIndex(ROW_COUNT-1, COL_COUNT-1));
145     }
146   }
147 }
148
149 void ScoreTableModel::prev()
150 {
151   if (score && course) {
152     if (currentScore > 0) {
153       currentScore--;
154       score = scoreList.at(currentScore);
155       course = findCourse(score->getClubName(), score->getCourseName());
156       emit dataChanged(createIndex(0, 0), createIndex(ROW_COUNT-1, COL_COUNT-1));
157     }
158   }
159 }
160
161 int ScoreTableModel::rowCount(const QModelIndex & parent) const
162 {
163   return 8;
164 }
165  
166 int ScoreTableModel::columnCount(const QModelIndex & parent) const
167 {
168   return 9 + 2; // 2 for in/out and tot columns
169 }
170
171 QModelIndex ScoreTableModel::index(int row, int column, const QModelIndex &parent) const
172 {
173   if (hasIndex(row, column, parent)) {
174     int flag = (parent.column() > 0) ? parent.column() : 0;
175     //qDebug() << "index() " << row << "/" << column << "/ flag: " << flag <<"//" << parent;
176     return createIndex(row, column, flag);
177   }
178   else {
179     return QModelIndex();
180   }
181 }
182
183 QVariant ScoreTableModel::data(const QModelIndex &index, int role) const
184 {
185   if (!index.isValid())
186     return QVariant();
187
188   if (!course || !score)
189     return QVariant();
190
191   int row = index.row();
192   int col = index.column();
193
194   //
195   // ALIGNMENT
196   //
197   if (role == Qt::TextAlignmentRole ) {
198     return Qt::AlignCenter;
199   }
200
201   if (index.column() > 10)
202     return QVariant();
203
204   //
205   // COLORS
206   //
207   QColor colorHoleBg(Qt::black);
208   QColor colorHoleFg(Qt::white);
209   QColor colorBirdie(Qt::yellow);
210   QColor colorPar(Qt::green);
211   QColor colorBogey(Qt::darkGreen);
212   QColor colorDoubleBogey(Qt::cyan);
213   QColor colorBad(Qt::white);
214   QColor colorSubTotal(Qt::lightGray);
215   QColor colorTotal(Qt::gray);
216
217   if (role == Qt::ForegroundRole) {
218     if (row == ROW_HOLE || row == ROW_HOLE_2) {
219         QBrush brush(colorHoleFg);
220         return brush;
221     }
222   }
223   if (role == Qt::BackgroundRole) {
224     int par = course->getPar(col).toInt();
225     int shots = score->getScore(col).toInt();
226
227     // Hole numbers 1-18
228     if (row == ROW_HOLE || row == ROW_HOLE_2) {
229         QBrush brush(colorHoleBg);
230         return brush;
231     }
232
233     if (row == ROW_SCORE || row == ROW_SCORE_2) {
234       if (col == 10 && row == ROW_SCORE_2) {
235         // Total score
236         QBrush brush(colorTotal);
237         return brush;
238       }
239       if (col == 9) {
240         // In and Out scores
241         QBrush brush(colorSubTotal);
242         return brush;
243       }
244       if (col < 9) {
245         if (shots == par) {
246           // Par
247           QBrush brush(colorPar);
248           return brush;
249         }
250         if (shots == (par-1)) {
251           // Birdie
252           QBrush brush(colorBirdie);
253           return brush;
254         }
255         if (shots == (par+1)) {
256           // Bogey
257           QBrush brush(colorBogey);
258           return brush;
259         }
260         if (shots == (par+2)) {
261           // Double Bogey
262           QBrush brush(colorDoubleBogey);
263           return brush;
264         }
265       }
266     }
267     return QVariant();
268   }
269   //
270   // FONT
271   //
272   if (role == Qt::FontRole) {
273     if (row == ROW_SCORE_2 && col == 10) {
274         QFont font;
275         font.setBold(true);
276         return font;
277     }
278   }
279   //
280   // DATA
281   //
282   if (role == Qt::DisplayRole) {
283
284     if (col == 9) {
285       // In/out label
286       if (row == ROW_HOLE)
287         return QString("Out");
288       if (row == ROW_HOLE_2)
289         return QString("In");
290
291       // In/Out for par
292       if (row == ROW_PAR)
293         return course->getTotal(TotalOut);
294       if (row == ROW_PAR_2)
295         return course->getTotal(TotalIn);
296
297       // In/Out for score
298       if (row == ROW_SCORE)
299         return score->getTotal(TotalOut);
300       if (row == ROW_SCORE_2)
301         return score->getTotal(TotalIn);
302       
303     }
304     else if (col == 10) {
305       // Total label
306       if (row == ROW_HOLE_2)
307         return QString("Tot");
308       // Total score
309       if (row == ROW_PAR_2)
310         return course->getTotal(Total);
311       if (row == ROW_SCORE_2)
312         return score->getTotal(Total);
313     }
314     else {
315       // data cells
316       switch(row) {
317       case ROW_HOLE:
318         return col + 1;
319       case ROW_HOLE_2:
320         return col + 10;
321       case ROW_PAR:
322         return course->getPar(col); 
323       case ROW_PAR_2:
324         return course->getPar(col + 9); 
325       case ROW_HCP: 
326         return course->getHcp(col); 
327       case ROW_HCP_2: 
328         return course->getHcp(col + 9);
329       case ROW_SCORE: 
330         return score->getScore(col);
331       case ROW_SCORE_2: 
332         return score->getScore(col + 9);
333       }
334     }
335   }
336   return QVariant();
337 }
338
339 int ScoreTableModel::setItem(int row, int col, int data)
340 {
341   emit dataChanged(createIndex(row, col), createIndex(row, col));
342   return 1;
343 }
344
345 QVariant ScoreTableModel::headerData(int section, Qt::Orientation orientation, int role) const
346 {
347   if (role != Qt::DisplayRole)
348          return QVariant();
349
350     // TODO: how to diff between the two table views (no index?)
351
352     if (orientation == Qt::Horizontal)
353       if (section >= 0 && section <= 8)
354         return QString("%1").arg(section+1);
355       else if (section == 9)
356         return QString(""); // was: I/O
357       else
358         return QString(""); // was: Tot
359     else {
360       switch(section) {
361       case ROW_PAR: 
362       case ROW_PAR_2: 
363         return QString("Par");
364       case ROW_HCP: 
365       case ROW_HCP_2: 
366         return QString("HCP");
367       case ROW_SCORE: 
368       case ROW_SCORE_2: 
369         return QString("Score");
370       }
371     }
372     return QVariant();
373 }
374