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