1 #include "weightdata.h"
5 #include <QtAlgorithms>
11 WeightDataModel::WeightDataModel(QString &datafilename, QObject *parent) :
12 QAbstractTableModel(parent), datafile(datafilename)
18 void WeightDataModel::clear()
23 Qt::ItemFlags WeightDataModel::flags(const QModelIndex &index) const
26 return Qt::ItemIsEnabled;
27 switch(index.column()) {
28 case 0: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
29 case 1: return Qt::ItemIsEnabled | Qt::ItemIsEditable;
30 default: return Qt::NoItemFlags;
34 QVariant WeightDataModel::data(const QModelIndex &index, int role) const
36 if (!index.isValid() || index.row() >= rowCount(QModelIndex())
37 || index.column() >= columnCount(QModelIndex()))
40 if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::SizeHintRole)
43 if (role == Qt::SizeHintRole) {
44 if (index.column() == 0)
50 if (index.column() == 0) {
51 return weights.at(index.row()).date.toString(Qt::ISODate);
54 if (role == Qt::DisplayRole)
55 return QString("%1 %2").arg(weights.at(index.row()).weight,5,'f',1)
56 .arg(Settings::weightUnit());
58 return weights.at(index.row()).weight;
64 bool WeightDataModel::setData(const QModelIndex &index, const QVariant &value, int role)
66 if (!index.isValid() || role != Qt::EditRole)
68 switch (index.column()) {
70 weights[index.row()].date = value.toDate();
73 double weight = value.toDouble();
74 weights[index.row()].weight = weight;
77 default: return false;
80 emit(dataChanged(index, index));
86 bool WeightDataModel::setDataForRow(int row, const DateWeight &dw)
88 if (row < 0 || row >= weights.size())
92 QModelIndex a = index(row, 0);
93 QModelIndex b = index(row, 1);
95 emit(dataChanged(a, b));
99 // Sets data for a date. Adds a new row for the date if it doesn't exist.
100 void WeightDataModel::setWeightForDate(const QDate &date, double weight)
102 int row = rowOfDate(date);
104 row = rowForNewDate(date);
107 DateWeight dw = {date, weight};
108 setDataForRow(row, dw);
111 void WeightDataModel::setWeightForDate(const WeightDataModel::DateWeight &dw)
113 setWeightForDate(dw.date, dw.weight);
116 QVariant WeightDataModel::headerData(int section, Qt::Orientation orientation, int role) const
118 if (role != Qt::DisplayRole)
120 if (orientation == Qt::Horizontal) {
121 return section == 0 ? tr("Date") : tr("Weight");
124 return QString("%1").arg(section);
128 // Insert count "empty" rows starting from row.
129 // DOESN'T WRITE DATA BACK TO DISK to allow inserter
130 // to modify the row, then write it.
131 bool WeightDataModel::insertRows(int row, int count, const QModelIndex &/*parent*/)
133 beginInsertRows(QModelIndex(), row, row+count-1);
135 //empty.date.setDate(2000,1,1);
138 weights.insert(row, empty);
143 bool WeightDataModel::removeRows(int row, int count, const QModelIndex &/*parent*/)
145 beginRemoveRows(QModelIndex(), row, row+count-1);
147 weights.removeAt(row);
153 //Returns the row of the date or -1 if it doesn't exist.
154 int WeightDataModel::rowOfDate(const QDate &date) const
156 for(int i=0; i<weights.size(); i++)
157 if (weights[i].date == date)
161 QModelIndex WeightDataModel::indexOfDate(const QDate &date) const
163 return index(rowOfDate(date), 0);
166 bool WeightDataModel::dateExists(const QDate &date) const
168 return rowOfDate(date) != -1;
171 int WeightDataModel::rowForNewDate(const QDate &date) const
173 if (weights.size() == 0)
175 if (date < weights.first().date)
177 for(int i=1; i<weights.size(); i++) {
178 if (weights.at(i-1).date < date
179 && weights.at(i).date > date)
182 if (date > weights.last().date)
183 return weights.size();
184 assert(0 && "UNREACHABLE");
188 void WeightDataModel::writeToDisk()
190 if (QFile::exists(datafile.fileName())) {
191 QString backupfile = datafile.fileName()+".bak";
192 if (QFile::exists(backupfile))
193 QFile::remove(backupfile);
194 QFile::copy(datafile.fileName(), backupfile);
196 if (datafile.open(QIODevice::WriteOnly | QIODevice::Text)) {
197 QTextStream stream(&datafile);
198 foreach(DateWeight w, weights)
199 stream << w.date.toString(Qt::ISODate) << ';' << w.weight << "\n";
204 void WeightDataModel::readFromDisk()
206 if (!datafile.exists()) {
210 if (datafile.open(QIODevice::ReadOnly | QIODevice::Text)) {
212 QTextStream stream(&datafile);
213 QString line = stream.readLine();
214 while (!line.isNull()) {
215 QStringList parts = line.split(';');
216 if (parts.size() != 2) {
217 throw(QString("Invalid line in file: '%1'").arg(line));
220 w.date = QDate::fromString(parts[0], Qt::ISODate);
221 if (!w.date.isValid()) {
222 throw(QString("Invalid date in file: '%1'").arg(parts[0]));
225 w.weight = parts[1].toDouble(&ok);
227 throw(QString("Invalid weight in file: '%1'").arg(parts[1]));
229 weights.push_back(w);
230 line = stream.readLine();
237 throw(QString("Could not read file '%1'").arg(datafile.fileName()));