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