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