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