File indexing completed on 2025-02-09 07:08:06
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im> 0003 * SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-3.0-or-later 0006 */ 0007 0008 #include "recordingmodel.h" 0009 0010 #include <QFile> 0011 #include <QStandardPaths> 0012 #include <QJsonObject> 0013 #include <QDebug> 0014 #include <QJsonDocument> 0015 #include <QJsonArray> 0016 #include <QDir> 0017 0018 #include "utils.h" 0019 0020 const QString DEF_RECORD_PREFIX = QStringLiteral("clip"); 0021 0022 RecordingModel* RecordingModel::instance() 0023 { 0024 static RecordingModel *recordingModel = new RecordingModel(qApp); 0025 return recordingModel; 0026 } 0027 0028 RecordingModel::RecordingModel(QObject *parent) 0029 : QAbstractListModel{ parent } 0030 , m_settings{ new QSettings(parent) } 0031 { 0032 load(); 0033 } 0034 0035 RecordingModel::~RecordingModel() 0036 { 0037 save(); 0038 } 0039 0040 int RecordingModel::count() const 0041 { 0042 return m_recordings.size(); 0043 } 0044 0045 void RecordingModel::load() 0046 { 0047 QJsonDocument doc = QJsonDocument::fromJson(m_settings->value(QStringLiteral("recordings")).toString().toUtf8()); 0048 0049 beginResetModel(); 0050 0051 const auto array = doc.array(); 0052 std::transform(array.begin(), array.end(), std::back_inserter(m_recordings), [this](const QJsonValue &rec) { 0053 return new Recording(this, rec.toObject()); 0054 }); 0055 0056 // check if file exists, and delete recording if it doesn't 0057 for (int i = 0; i < m_recordings.size(); ++i) { 0058 if (!QFile::exists(m_recordings[i]->filePath())) { 0059 m_recordings.erase(m_recordings.begin() + i); 0060 --i; 0061 } 0062 } 0063 save(); 0064 0065 endResetModel(); 0066 Q_EMIT countChanged(); 0067 } 0068 0069 void RecordingModel::save() 0070 { 0071 QJsonArray arr; 0072 0073 const auto recordings = qAsConst(m_recordings); 0074 std::transform(recordings.begin(), recordings.end(), std::back_inserter(arr), [](const Recording *recording) { 0075 return QJsonValue(recording->toJson()); 0076 }); 0077 0078 m_settings->setValue(QStringLiteral("recordings"), QString::fromStdString(QJsonDocument(arr).toJson(QJsonDocument::Compact).toStdString())); 0079 m_settings->sync(); 0080 } 0081 0082 int RecordingModel::rowCount(const QModelIndex &parent) const 0083 { 0084 if (parent.isValid()) { 0085 return 0; 0086 } 0087 return m_recordings.size(); 0088 } 0089 0090 QVariant RecordingModel::data(const QModelIndex &index, int role) const 0091 { 0092 if (!checkIndex(index)) { 0093 return QVariant(); 0094 } 0095 if (role != RecordingRole) { 0096 return QVariant(); 0097 } 0098 0099 auto *recording = m_recordings[index.row()]; 0100 return recording ? QVariant::fromValue(recording) : QVariant(); 0101 } 0102 0103 QHash<int, QByteArray> RecordingModel::roleNames() const 0104 { 0105 return {{RecordingRole, "recording"}}; 0106 } 0107 0108 QList<Recording *> &RecordingModel::recordings() 0109 { 0110 return m_recordings; 0111 } 0112 0113 QString RecordingModel::nextDefaultRecordingName() 0114 { 0115 // used names set 0116 QSet<QString> usedNames; 0117 0118 for (const auto &rec : qAsConst(m_recordings)) { 0119 usedNames.insert(rec->fileName()); 0120 } 0121 0122 // add files in storage location 0123 QDir storageLocation{QStandardPaths::writableLocation(QStandardPaths::MusicLocation)}; 0124 for (QFileInfo &info : storageLocation.entryInfoList()) { 0125 auto name = info.fileName(); 0126 auto list = name.split(QStringLiteral(".")); 0127 0128 // insert without file extension 0129 if (list.size() > 0) { 0130 usedNames.insert(list[0]); 0131 } 0132 } 0133 0134 // determine valid clip name (ex. clip_0001, clip_0002, etc.) 0135 0136 int num = 1; 0137 QString build = QStringLiteral("0001"); 0138 0139 while (usedNames.contains(DEF_RECORD_PREFIX + QStringLiteral("_") + build)) { 0140 num++; 0141 build = QString::number(num); 0142 while (build.length() < 4) { 0143 build = QStringLiteral("0") + build; 0144 } 0145 } 0146 0147 return DEF_RECORD_PREFIX + QStringLiteral("_") + build; 0148 } 0149 0150 0151 void RecordingModel::insertRecording(QString filePath, QString fileName, QDateTime recordDate, int recordingLength) 0152 { 0153 qDebug() << "Adding recording " << filePath; 0154 0155 beginInsertRows(QModelIndex(), 0, 0); 0156 0157 m_recordings.insert(0, new Recording(this, filePath, fileName, recordDate, recordingLength)); 0158 save(); 0159 0160 endInsertRows(); 0161 Q_EMIT countChanged(); 0162 } 0163 0164 void RecordingModel::deleteRecording(const int index) 0165 { 0166 qDebug() << "Removing recording " << m_recordings[index]->filePath(); 0167 0168 beginRemoveRows(QModelIndex(), index, index); 0169 0170 QFile::remove(m_recordings[index]->filePath()); 0171 m_recordings.removeAt(index); 0172 save(); 0173 0174 endRemoveRows(); 0175 Q_EMIT countChanged(); 0176 } 0177