1 | /* |
2 | Copyright (C) 2014 by Elvis Angelaccio <elvis.angelaccio@kdemail.net> |
3 | |
4 | This file is part of Kronometer. |
5 | |
6 | Kronometer is free software: you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation, either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | Kronometer is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with Kronometer. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include "lapmodel.h" |
21 | |
22 | #include <KLocale> |
23 | |
24 | #include <QTime> |
25 | #include <QDomElement> |
26 | |
27 | LapModel::LapModel(QObject* parent): QAbstractTableModel(parent) {} |
28 | |
29 | int LapModel::columnCount(const QModelIndex& parent) const |
30 | { |
31 | Q_UNUSED(parent); |
32 | |
33 | return LAP_TAG_NUMBER; |
34 | } |
35 | |
36 | int LapModel::rowCount(const QModelIndex& parent) const |
37 | { |
38 | Q_UNUSED(parent); |
39 | |
40 | return timeList.size(); |
41 | } |
42 | |
43 | QVariant LapModel::data(const QModelIndex& index, int role) const |
44 | { |
45 | if (!index.isValid()) { |
46 | return QVariant::Invalid; |
47 | } |
48 | |
49 | if (index.row() >= timeList.size() || index.row() < 0) { |
50 | return QVariant::Invalid; |
51 | } |
52 | |
53 | if (role == Qt::DisplayRole) { |
54 | QVariant variant; |
55 | |
56 | switch (index.column()) { |
57 | case NUMBER: |
58 | variant = QString::number(index.row()); |
59 | break; |
60 | |
61 | case REL_TIME: |
62 | variant = relativeLapTime(index.row()); |
63 | break; |
64 | |
65 | case ABS_TIME: |
66 | variant = absoluteLapTime(index.row()); |
67 | break; |
68 | } |
69 | |
70 | return variant; |
71 | } |
72 | |
73 | return QVariant::Invalid; |
74 | } |
75 | |
76 | |
77 | QVariant LapModel::(int section, Qt::Orientation orientation, int role) const |
78 | { |
79 | if (role == Qt::DisplayRole) { |
80 | if (orientation == Qt::Horizontal) { |
81 | switch (section) { |
82 | case NUMBER: |
83 | return i18n("Lap #" ); |
84 | break; |
85 | |
86 | case REL_TIME: |
87 | return i18n("Lap time" ); |
88 | break; |
89 | |
90 | case ABS_TIME: |
91 | return i18n("Global time" ); |
92 | break; |
93 | } |
94 | } |
95 | } |
96 | |
97 | return QVariant::Invalid; |
98 | } |
99 | |
100 | void LapModel::setTimeFormat(const TimeFormat &format) |
101 | { |
102 | timeFormat = format; |
103 | } |
104 | |
105 | bool LapModel::lapToXml(QDomElement& element, const QString& attributeName, int lapIndex) |
106 | { |
107 | if (lapIndex < 0 or lapIndex >= timeList.size() or attributeName.isEmpty()) { |
108 | return false; |
109 | } |
110 | |
111 | QTime zero(0, 0); |
112 | |
113 | element.setAttribute(attributeName, zero.msecsTo(timeList.at(lapIndex))); |
114 | |
115 | return true; |
116 | } |
117 | |
118 | bool LapModel::lapFromXml(const QDomElement& element, const QString& attributeName) |
119 | { |
120 | if (attributeName.isEmpty()) { |
121 | return false; |
122 | } |
123 | |
124 | QString attributeValue = element.attribute(attributeName); |
125 | qint64 milliseconds = attributeValue.toLongLong(); |
126 | |
127 | if (milliseconds == 0) { |
128 | return false; // invalid attribute name or value |
129 | } |
130 | |
131 | QTime t(0, 0); |
132 | t = t.addMSecs(milliseconds); |
133 | beginInsertRows(QModelIndex(),timeList.size(),timeList.size()); // i.e. append the new row at table end |
134 | timeList.append(t); |
135 | endInsertRows(); |
136 | |
137 | return true; |
138 | } |
139 | |
140 | QString LapModel::relativeLapTime(int lapIndex) const |
141 | { |
142 | if (lapIndex < 0 or lapIndex >= timeList.size()) { |
143 | return QString(); |
144 | } |
145 | |
146 | QString time; |
147 | |
148 | if (timeList.size() > 1 and lapIndex > 0) { // compute diff only starting from 2nd entry |
149 | QTime prev = timeList.at(lapIndex - 1); |
150 | QTime target = timeList.at(lapIndex); |
151 | QTime diff(0, 0); |
152 | diff = diff.addMSecs(prev.msecsTo(target)); |
153 | |
154 | time = timeFormat.format(diff); |
155 | } |
156 | else { // first lap entry |
157 | time = timeFormat.format(timeList.first()); |
158 | } |
159 | |
160 | return time; |
161 | } |
162 | |
163 | QString LapModel::absoluteLapTime(int lapIndex) const |
164 | { |
165 | if (lapIndex < 0 or lapIndex >= timeList.size()) { |
166 | return QString(); |
167 | } |
168 | |
169 | return timeFormat.format(timeList.at(lapIndex)); |
170 | } |
171 | |
172 | bool LapModel::isEmpty() const |
173 | { |
174 | return timeList.isEmpty(); |
175 | } |
176 | |
177 | void LapModel::onLap(const QTime& lapTime) |
178 | { |
179 | beginInsertRows(QModelIndex(),timeList.size(),timeList.size()); // i.e. append the new row at table end |
180 | timeList.append(lapTime); |
181 | endInsertRows(); |
182 | } |
183 | |
184 | void LapModel::onClear() |
185 | { |
186 | beginResetModel(); |
187 | timeList.clear(); |
188 | endResetModel(); |
189 | } |
190 | |
191 | QDataStream& operator<<(QDataStream& out, const LapModel& m) |
192 | { |
193 | out << m.timeList; |
194 | |
195 | return out; |
196 | } |
197 | |
198 | QDataStream& operator>>(QDataStream& in, LapModel& m) |
199 | { |
200 | QList<QTime> temp; |
201 | in >> temp; |
202 | |
203 | for (int i = 0; i < temp.size(); i++) { |
204 | m.beginInsertRows(QModelIndex(), i, i); |
205 | m.timeList.append(temp.at(i)); |
206 | m.endInsertRows(); |
207 | } |
208 | |
209 | return in; |
210 | } |
211 | |