File indexing completed on 2024-05-12 05:54:14

0001 /*
0002     SPDX-FileCopyrightText: 2014 Elvis Angelaccio <elvis.angelaccio@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "lapmodel.h"
0008 
0009 #include <KLocalizedString>
0010 
0011 #include <QTime>
0012 
0013 LapModel::LapModel(QObject* parent) : QAbstractTableModel(parent)
0014 {}
0015 
0016 int LapModel::columnCount(const QModelIndex& parent) const
0017 {
0018     Q_UNUSED(parent)
0019 
0020     return m_roles.count();
0021 }
0022 
0023 int LapModel::rowCount(const QModelIndex& parent) const
0024 {
0025     Q_UNUSED(parent)
0026 
0027     return m_laps.size();
0028 }
0029 
0030 QVariant LapModel::data(const QModelIndex& index, int role) const
0031 {
0032     if (!index.isValid()) {
0033         return QVariant::Invalid;
0034     }
0035 
0036     if (index.row() >= rowCount() || index.row() < 0) {
0037         return QVariant::Invalid;
0038     }
0039 
0040     if (role == Qt::DisplayRole) {
0041         return data(index, Qt::UserRole + index.column());
0042     }
0043 
0044     switch (static_cast<Roles>(role)) {
0045     case Roles::LapIdRole:
0046         return index.row() + 1;
0047     case Roles::RelativeTimeRole:
0048         return m_laps.at(index.row()).relativeTime();
0049     case Roles::AbsoluteTimeRole:
0050         return m_laps.at(index.row()).absoluteTime();
0051     case Roles::NoteRole:
0052         return m_laps.at(index.row()).note();
0053     case Roles::LapRole:
0054         return QVariant::fromValue(m_laps.at(index.row()));
0055     }
0056 
0057     if (role == Qt::EditRole && index.column() == columnForRole(Roles::NoteRole)) {
0058         // prevent the disappear of the old value when double-clicking the item
0059         return m_laps.at(index.row()).note();
0060     }
0061 
0062     return QVariant::Invalid;
0063 }
0064 
0065 QVariant LapModel::headerData(int section, Qt::Orientation orientation, int role) const
0066 {
0067     if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
0068         return QVariant::Invalid;
0069 
0070     switch (roleForColumn(section)) {
0071     case Roles::LapIdRole:
0072         return i18nc("lap number", "Lap #");
0073     case Roles::RelativeTimeRole:
0074         return i18nc("@title:column", "Lap Time");
0075     case Roles::AbsoluteTimeRole:
0076         return i18nc("@title:column", "Global Time");
0077     case Roles::NoteRole:
0078         return i18nc("@title:column", "Note");
0079     case Roles::LapRole:
0080         break;
0081     }
0082 
0083     return QVariant::Invalid;
0084 }
0085 
0086 bool LapModel::setData(const QModelIndex& index, const QVariant& value, int role)
0087 {
0088     if (!index.isValid() || role != Qt::EditRole)
0089         return false;
0090 
0091     if (index.column() != columnForRole(Roles::NoteRole))
0092         return false;
0093 
0094     m_laps[index.row()].setNote(value.toString());
0095     Q_EMIT dataChanged(index, index);
0096 
0097     return true;
0098 }
0099 
0100 Qt::ItemFlags LapModel::flags(const QModelIndex& index) const
0101 {
0102     if (!index.isValid())
0103         return Qt::ItemIsEnabled;
0104 
0105     if (index.column() != columnForRole(Roles::NoteRole))
0106         return QAbstractTableModel::flags(index);
0107 
0108     return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
0109 }
0110 
0111 void LapModel::setTimeFormat(const TimeFormat& format)
0112 {
0113     m_timeFormat = format;
0114 
0115     if (!isEmpty()) {
0116         reload();
0117     }
0118 }
0119 
0120 void LapModel::append(const Lap& lap)
0121 {
0122     // Append the new row at the end.
0123     beginInsertRows(QModelIndex(), rowCount(), rowCount());
0124 
0125     // Either the time of the first lap or the time relative to the last lap.
0126     const auto relativeTime = m_laps.isEmpty() ? lap.time() : m_laps.last().timeTo(lap);
0127 
0128     auto newLap = Lap {lap};
0129     newLap.setRelativeTime(m_timeFormat.format(relativeTime));
0130     newLap.setAbsoluteTime(m_timeFormat.format(newLap.time()));
0131 
0132     m_laps.append(newLap);
0133     endInsertRows();
0134 }
0135 
0136 bool LapModel::isEmpty() const
0137 {
0138     return m_laps.isEmpty();
0139 }
0140 
0141 int LapModel::columnForRole(LapModel::Roles role) const
0142 {
0143     return m_roles.indexOf(role);
0144 }
0145 
0146 void LapModel::addLap(const QTime& lapTime)
0147 {
0148     append(Lap {lapTime});
0149 }
0150 
0151 void LapModel::clear()
0152 {
0153     beginResetModel();
0154     m_laps.clear();
0155     endResetModel();
0156 }
0157 
0158 void LapModel::reload()
0159 {
0160     const auto laps = m_laps;
0161     clear();
0162 
0163     for (const auto& lap : laps) {
0164         append(lap);
0165     }
0166 }
0167 
0168 LapModel::Roles LapModel::roleForColumn(int column) const
0169 {
0170     return m_roles.at(column);
0171 }
0172 
0173 #include "moc_lapmodel.cpp"