File indexing completed on 2024-05-12 05:54:14
0001 /* 0002 SPDX-FileCopyrightText: 2015 Elvis Angelaccio <elvis.angelaccio@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "sessionmodel.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include <QDebug> 0012 #include <QFile> 0013 #include <QJsonArray> 0014 #include <QJsonDocument> 0015 #include <QJsonObject> 0016 #include <QStandardPaths> 0017 0018 SessionModel::SessionModel(QObject *parent) : QAbstractTableModel(parent) 0019 { 0020 QFile saveFile {QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1String("/sessions.json")}; 0021 if (saveFile.exists()) { 0022 if (saveFile.open(QIODevice::ReadOnly)) { 0023 auto saveData = saveFile.readAll(); 0024 auto saveDoc = QJsonDocument::fromJson(saveData); 0025 read(saveDoc.object()); 0026 } else { 0027 qDebug().nospace() << "cannot open " << saveFile.fileName() << ": " << saveFile.errorString(); 0028 } 0029 } 0030 0031 connect(this, &QAbstractTableModel::dataChanged, this, &SessionModel::slotWriteData); 0032 connect(this, &QAbstractTableModel::rowsInserted, this, &SessionModel::slotWriteData); 0033 connect(this, &QAbstractTableModel::rowsRemoved, this, &SessionModel::slotWriteData); 0034 } 0035 0036 int SessionModel::columnCount(const QModelIndex& parent) const 0037 { 0038 Q_UNUSED(parent) 0039 0040 return m_roles.count(); 0041 } 0042 0043 int SessionModel::rowCount(const QModelIndex& parent) const 0044 { 0045 Q_UNUSED(parent) 0046 0047 return m_sessionList.size(); 0048 } 0049 0050 QVariant SessionModel::data(const QModelIndex& index, int role) const 0051 { 0052 if (!index.isValid()) { 0053 return QVariant::Invalid; 0054 } 0055 0056 if (index.row() >= rowCount() || index.row() < 0) { 0057 return QVariant::Invalid; 0058 } 0059 0060 if (role == Qt::DisplayRole) { 0061 return data(index, Qt::UserRole + index.column()); 0062 } 0063 0064 switch (static_cast<Roles>(role)) { 0065 case Roles::SessionIdRole: 0066 return QString::number(index.row() + 1); 0067 case Roles::NameRole: 0068 return m_sessionList.at(index.row()).name(); 0069 case Roles::DateRole: 0070 return m_sessionList.at(index.row()).date(); 0071 case Roles::NoteRole: 0072 return m_sessionList.at(index.row()).note(); 0073 case Roles::SessionRole: 0074 return QVariant::fromValue(m_sessionList.at(index.row())); 0075 } 0076 0077 if (role == Qt::EditRole && index.column() == columnForRole(Roles::NameRole)) { 0078 // prevent the disappear of the old value when double-clicking the item 0079 return m_sessionList.at(index.row()).name(); 0080 } 0081 0082 if (role == Qt::EditRole && index.column() == columnForRole(Roles::NoteRole)) { 0083 return m_sessionList.at(index.row()).note(); 0084 } 0085 0086 return QVariant::Invalid; 0087 } 0088 0089 0090 QVariant SessionModel::headerData(int section, Qt::Orientation orientation, int role) const 0091 { 0092 if (role != Qt::DisplayRole || orientation != Qt::Horizontal) 0093 return QVariant::Invalid; 0094 0095 switch (roleForColumn(section)) { 0096 case Roles::SessionIdRole: 0097 return i18nc("session number", "Session #"); 0098 case Roles::NameRole: 0099 return i18n("Name"); 0100 case Roles::DateRole: 0101 return i18n("Date"); 0102 case Roles::NoteRole: 0103 return i18n("Note"); 0104 case Roles::SessionRole: 0105 break; 0106 } 0107 0108 return QVariant::Invalid; 0109 } 0110 0111 bool SessionModel::setData(const QModelIndex& index, const QVariant& value, int role) 0112 { 0113 if (!index.isValid() || role != Qt::EditRole) 0114 return false; 0115 0116 if (index.column() == columnForRole(Roles::NameRole)) { 0117 if (value.toString().isEmpty()) 0118 return false; 0119 0120 m_sessionList[index.row()].setName(value.toString()); 0121 Q_EMIT dataChanged(index, index); 0122 0123 return true; 0124 } 0125 0126 if (index.column() == columnForRole(Roles::NoteRole)) { 0127 m_sessionList[index.row()].setNote(value.toString()); 0128 Q_EMIT dataChanged(index, index); 0129 0130 return true; 0131 } 0132 0133 return false; 0134 } 0135 0136 Qt::ItemFlags SessionModel::flags(const QModelIndex& index) const 0137 { 0138 if (!index.isValid()) 0139 return Qt::ItemIsEnabled; 0140 0141 if (isEditable(index)) 0142 return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; 0143 0144 return QAbstractTableModel::flags(index); 0145 } 0146 0147 bool SessionModel::removeRows(int row, int count, const QModelIndex& parent) 0148 { 0149 if (row < 0 || row + count - 1 >= rowCount()) 0150 return false; 0151 0152 beginRemoveRows(parent, row, row + count - 1); 0153 0154 for (int i = 0; i < count; i++) { 0155 m_sessionList.removeAt(row); 0156 } 0157 0158 endRemoveRows(); 0159 0160 return true; 0161 } 0162 0163 void SessionModel::append(const Session& session) 0164 { 0165 beginInsertRows(QModelIndex(), rowCount(), rowCount()); // i.e. append the new row at the table end 0166 m_sessionList.append(session); 0167 endInsertRows(); 0168 } 0169 0170 void SessionModel::update(Session& session) 0171 { 0172 int i = m_sessionList.indexOf(session); 0173 0174 if (i == -1) 0175 return; 0176 0177 session.setDate(QDateTime::currentDateTime()); 0178 m_sessionList[i] = session; 0179 0180 Q_EMIT dataChanged({}, {}); 0181 } 0182 0183 bool SessionModel::isEmpty() const 0184 { 0185 return m_sessionList.isEmpty(); 0186 } 0187 0188 bool SessionModel::isEditable(const QModelIndex& index) const 0189 { 0190 auto role = roleForColumn(index.column()); 0191 return role == Roles::NameRole || role == Roles::NoteRole; 0192 } 0193 0194 void SessionModel::read(const QJsonObject& json) 0195 { 0196 const auto sessions = json[QStringLiteral("sessions")].toArray(); 0197 for (const auto& session : sessions) { 0198 append(Session::fromJson(session.toObject())); 0199 } 0200 } 0201 0202 void SessionModel::slotWriteData() 0203 { 0204 QFile saveFile {QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1String("/sessions.json")}; 0205 if (!saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { 0206 qDebug().nospace() << "cannot open " << saveFile.fileName() << ": " << saveFile.errorString(); 0207 return; 0208 } 0209 0210 auto json = QJsonObject {}; 0211 json[QStringLiteral("sessions")] = jsonSessions(); 0212 0213 auto saveDoc = QJsonDocument {json}; 0214 saveFile.write(saveDoc.toJson()); 0215 } 0216 0217 int SessionModel::columnForRole(SessionModel::Roles role) const 0218 { 0219 return m_roles.indexOf(role); 0220 } 0221 0222 SessionModel::Roles SessionModel::roleForColumn(int column) const 0223 { 0224 return m_roles.at(column); 0225 } 0226 0227 QJsonArray SessionModel::jsonSessions() const 0228 { 0229 auto array = QJsonArray {}; 0230 const auto sessions = m_sessionList; 0231 for (const auto& session : sessions) { 0232 auto object = QJsonObject {}; 0233 session.write(object); 0234 array.append(object); 0235 } 0236 0237 return array; 0238 } 0239 0240 0241 #include "moc_sessionmodel.cpp"