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