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