Mon, 06 Jun 2022 22:01:22 +0300
Giant refactor
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 - 2020 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "model.h" QString modelElementToString(const ModelElement &element) { return std::visit(overloaded{ [](const Colored<SubfileReference>& ref) { return QStringLiteral("1 %1 %2 %3") .arg(ref.color.index) .arg(transformToString(ref.transformation)) .arg(ref.name); }, [](const Colored<LineSegment>& seg) { return QStringLiteral("2 %1 %2 %3") .arg(seg.color.index) .arg(vertexToString(seg.p1)) .arg(vertexToString(seg.p2)); }, [](const Colored<Triangle>& triangle) { return QStringLiteral("3 %1 %2 %3 %4") .arg(triangle.color.index) .arg(vertexToString(triangle.p1)) .arg(vertexToString(triangle.p2)) .arg(vertexToString(triangle.p3)); }, [](const Colored<Quadrilateral>& quad) { return QStringLiteral("4 %1 %2 %3 %4 %5") .arg(quad.color.index) .arg(vertexToString(quad.p1)) .arg(vertexToString(quad.p2)) .arg(vertexToString(quad.p3)) .arg(vertexToString(quad.p4)); }, [](const Colored<ConditionalEdge>& cedge) { return QStringLiteral("5 %1 %2 %3 %4 %5") .arg(cedge.color.index) .arg(vertexToString(cedge.p1)) .arg(vertexToString(cedge.p2)) .arg(vertexToString(cedge.c1)) .arg(vertexToString(cedge.c2)); }, [](const Comment& comment) { return "0 " + comment.text; }, [](const Empty&) { return QStringLiteral(""); }, [](const ParseError& parseError) { return parseError.code; }, }, element); } Model::Model(QObject *parent) : QAbstractListModel{parent} { } Model::~Model() { } ModelId Model::append(const ModelElement &value) { const int position = static_cast<int>(this->body.size()); const ModelId id = this->runningId; this->runningId.value += 1; Q_EMIT this->beginInsertRows({}, position, position); this->body.push_back({value, id}); this->positions[id] = position; Q_EMIT this->endInsertRows(); return id; } const ModelElement &Model::at(int position) const { return this->body[position].data; } ModelId Model::idAt(int position) const { return this->body[position].id; } void Model::assignAt(int position, const ModelElement &element) { this->body[position].data = element; const QModelIndex index = this->index(position); Q_EMIT this->dataChanged(index, index); } std::optional<int> Model::find(ModelId id) const { return pointerToOptional(findInMap(this->positions, id)); } void Model::remove(int index) { if (index >= 0 and index < this->size()) { Q_EMIT this->beginRemoveRows({}, index, index); this->body.erase(this->body.begin() + index); Q_EMIT this->endRemoveRows(); } } int Model::rowCount(const QModelIndex &) const { return this->size(); } QVariant Model::data(const QModelIndex &index, int role) const { const int i = index.row(); switch(role) { /* case Qt::DecorationRole: return QPixmap{object->iconName()}.scaledToHeight(24); */ case Qt::DisplayRole: return modelElementToString(this->body[i].data); /* case Qt::ForegroundRole: return object->textRepresentationForeground(); case Qt::BackgroundRole: return object->textRepresentationBackground(); case Qt::FontRole: return object->textRepresentationFont(); */ default: return {}; } } const ModelElement &Model::operator[](int index) const { return this->body[index].data; } int Model::size() const { return this->body.size(); } void save(const Model &model, QIODevice *device) { QTextStream out{device}; for (int i = 0; i < model.size(); ++i) { out << modelElementToString(model[i]) << "\r\n"; } } /** * @brief Sets the path to the model * @param path New path to use */ void updateHeaderNameField(Model& model, const QString &name) { // Update the "Name: 1234.dat" comment if (model.size() >= 2) { if (const Comment* nameObject = std::get_if<Comment>(&model[1])) { if (nameObject->text.startsWith("Name: ")) { model[1] = Comment{"Name: " + name}; } } } }