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
27LapModel::LapModel(QObject* parent): QAbstractTableModel(parent) {}
28
29int LapModel::columnCount(const QModelIndex& parent) const
30{
31 Q_UNUSED(parent);
32
33 return LAP_TAG_NUMBER;
34}
35
36int LapModel::rowCount(const QModelIndex& parent) const
37{
38 Q_UNUSED(parent);
39
40 return timeList.size();
41}
42
43QVariant 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
77QVariant LapModel::headerData(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
100void LapModel::setTimeFormat(const TimeFormat &format)
101{
102 timeFormat = format;
103}
104
105bool 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
118bool 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
140QString 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
163QString 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
172bool LapModel::isEmpty() const
173{
174 return timeList.isEmpty();
175}
176
177void 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
184void LapModel::onClear()
185{
186 beginResetModel();
187 timeList.clear();
188 endResetModel();
189}
190
191QDataStream& operator<<(QDataStream& out, const LapModel& m)
192{
193 out << m.timeList;
194
195 return out;
196}
197
198QDataStream& 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