167 return parseError.code; |
164 return parseError.code; |
168 }, |
165 }, |
169 }, element); |
166 }, element); |
170 } |
167 } |
171 |
168 |
172 Model::Model(QObject *parent) : |
|
173 QAbstractListModel{parent} |
|
174 { |
|
175 } |
|
176 |
|
177 Model::~Model() |
|
178 { |
|
179 } |
|
180 |
|
181 ElementId Model::append(const ModelElement &value) |
|
182 { |
|
183 const std::size_t position = this->size(); |
|
184 const ElementId id = this->runningId; |
|
185 this->runningId.value += 1; |
|
186 const int row = narrow<int>(signed_cast(this->size())); |
|
187 Q_EMIT this->beginInsertRows({}, row, row); |
|
188 this->body.push_back({value, id}); |
|
189 this->positions[id] = position; |
|
190 Q_EMIT this->endInsertRows(); |
|
191 return id; |
|
192 } |
|
193 |
|
194 const ModelElement &Model::at(std::size_t position) const |
|
195 { |
|
196 return this->body[position].data; |
|
197 } |
|
198 |
|
199 ElementId Model::idAt(std::size_t position) const |
|
200 { |
|
201 return this->body[position].id; |
|
202 } |
|
203 |
|
204 void Model::assignAt(std::size_t position, const ModelElement &element) |
|
205 { |
|
206 this->body[position].data = element; |
|
207 const QModelIndex index = this->index(narrow<int>(signed_cast(position))); |
|
208 Q_EMIT this->dataChanged(index, index); |
|
209 } |
|
210 |
|
211 std::optional<std::size_t> Model::find(ElementId id) const |
|
212 { |
|
213 return pointerToOptional(findInMap(this->positions, id)); |
|
214 } |
|
215 |
|
216 template<typename K, typename V> |
169 template<typename K, typename V> |
217 void removeFromMap(std::map<K, V>& map, const K& key) |
170 void removeFromMap(std::map<K, V>& map, const K& key) |
218 { |
171 { |
219 const auto it = map.find(key); |
172 const auto it = map.find(key); |
220 if (it != map.end()) { |
173 if (it != map.end()) { |
221 map.erase(it); |
174 map.erase(it); |
222 } |
175 } |
223 } |
176 } |
224 |
177 |
225 void Model::remove(const std::size_t index) |
|
226 { |
|
227 if (index < this->body.size()) { |
|
228 const int row = narrow<int>(signed_cast(index)); |
|
229 Q_EMIT this->beginRemoveRows({}, row, row); |
|
230 removeFromMap(this->positions, this->body[index].id); |
|
231 this->body.erase(this->body.begin() + row); |
|
232 for (std::size_t i = index; i < this->body.size(); ++i) { |
|
233 this->positions[this->body[i].id] = i; |
|
234 } |
|
235 Q_EMIT this->endRemoveRows(); |
|
236 } |
|
237 } |
|
238 |
|
239 int Model::rowCount(const QModelIndex &) const |
|
240 { |
|
241 return narrow<int>(signed_cast(this->size())); |
|
242 } |
|
243 |
|
244 QVariant Model::data(const QModelIndex &index, int role) const |
|
245 { |
|
246 const std::size_t i = unsigned_cast(index.row()); |
|
247 const ModelElement& element = this->body[i].data; |
|
248 switch(role) |
|
249 { |
|
250 case Qt::DecorationRole: |
|
251 return iconForElement(element); |
|
252 case Qt::DisplayRole: |
|
253 return modelElementToString(element); |
|
254 /* |
|
255 case Qt::ForegroundRole: |
|
256 return object->textRepresentationForeground(); |
|
257 case Qt::BackgroundRole: |
|
258 return object->textRepresentationBackground(); |
|
259 case Qt::FontRole: |
|
260 return object->textRepresentationFont(); |
|
261 */ |
|
262 default: |
|
263 return {}; |
|
264 } |
|
265 } |
|
266 |
|
267 const ModelElement &Model::operator[](std::size_t index) const |
|
268 { |
|
269 return this->body[index].data; |
|
270 } |
|
271 |
|
272 std::size_t Model::size() const |
|
273 { |
|
274 return this->body.size(); |
|
275 } |
|
276 |
|
277 void Model::clear() |
|
278 { |
|
279 this->beginResetModel(); |
|
280 this->body.clear(); |
|
281 this->positions.clear(); |
|
282 this->runningId = {1}; |
|
283 this->endResetModel(); |
|
284 } |
|
285 |
|
286 void save(const Model &model, QTextStream* stream) |
178 void save(const Model &model, QTextStream* stream) |
287 { |
179 { |
288 for (std::size_t i = 0; i < model.size(); ++i) { |
180 *stream << model.toPlainText(); |
289 (*stream) << modelElementToString(model[i]) << "\r\n"; |
|
290 } |
|
291 } |
181 } |
292 |
182 |
293 /** |
183 /** |
294 * @brief Sets the path to the model |
184 * @brief Sets the path to the model |
295 * @param path New path to use |
185 * @param path New path to use |
296 */ |
186 */ |
297 void updateHeaderNameField(Model& model, const QString &name) |
187 void updateHeaderNameField(Model& model, const QString &name) |
298 { |
188 { |
|
189 #if 0 |
299 // Update the "Name: 1234.dat" comment |
190 // Update the "Name: 1234.dat" comment |
300 if (model.size() >= 2) { |
191 if (model.size() >= 2) { |
301 if (const Comment* nameObject = std::get_if<Comment>(&model[1])) { |
192 if (const Comment* nameObject = std::get_if<Comment>(&model[1])) { |
302 if (nameObject->text.startsWith("Name: ")) { |
193 if (nameObject->text.startsWith("Name: ")) { |
303 model[1] = Comment{"Name: " + name}; |
194 model[1] = Comment{"Name: " + name}; |
304 } |
195 } |
305 } |
196 } |
306 } |
197 } |
|
198 #endif |
307 } |
199 } |