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