diff -r 6988973515d2 -r ca23936b455b src/model.cpp
--- a/src/model.cpp Wed May 25 20:36:34 2022 +0300
+++ b/src/model.cpp Mon Jun 06 22:01:22 2022 +0300
@@ -16,254 +16,169 @@
* along with this program. If not, see .
*/
-#include
-#include
-#include
-#include
-#include
#include "model.h"
-#include "modeleditor.h"
-#include "documentmanager.h"
-/**
- * @brief Constructs a model
- * @param parent QObject parent to pass forward
- */
+QString modelElementToString(const ModelElement &element)
+{
+ return std::visit(overloaded{
+ [](const Colored& ref) {
+ return QStringLiteral("1 %1 %2 %3")
+ .arg(ref.color.index)
+ .arg(transformToString(ref.transformation))
+ .arg(ref.name);
+ },
+ [](const Colored& seg) {
+ return QStringLiteral("2 %1 %2 %3")
+ .arg(seg.color.index)
+ .arg(vertexToString(seg.p1))
+ .arg(vertexToString(seg.p2));
+ },
+ [](const Colored& 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& 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& 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}
{
}
-/**
- * @returns the amount of elements in the model
- */
-int Model::size() const
+Model::~Model()
+{
+}
+
+ModelId Model::append(const ModelElement &value)
{
- return static_cast(this->body.size());
+ const int position = static_cast(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;
}
-/**
- * @brief Looks up the object ID at the specified index. If out of bounds, returns NULL_ID.
- * @param index Index of object to look up
- * @return object ID
- */
-ldraw::id_t Model::at(int index) const
+ModelId Model::idAt(int position) const
+{
+ return this->body[position].id;
+}
+
+void Model::assignAt(int position, const ModelElement &element)
{
- if (index >= 0 and index < this->size())
- {
- return this->body[index]->id;
- }
- else
- {
- return ldraw::NULL_ID;
+ this->body[position].data = element;
+ const QModelIndex index = this->index(position);
+ Q_EMIT this->dataChanged(index, index);
+}
+
+std::optional 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();
}
}
-/**
- * @brief @overload QAbstractListModel::rowCount
- * @return size
- */
-int Model::rowCount(const QModelIndex&) const
+int Model::rowCount(const QModelIndex &) const
{
return this->size();
}
-/**
- * @brief @overload QAbstractListModel::data
- * @param index
- * @param role
- * @return QVariant
- */
-QVariant Model::data(const QModelIndex& index, int role) const
+QVariant Model::data(const QModelIndex &index, int role) const
{
- const ldraw::Object* object = (*this)[index.row()];
+ const int i = index.row();
switch(role)
{
+ /*
case Qt::DecorationRole:
return QPixmap{object->iconName()}.scaledToHeight(24);
+ */
case Qt::DisplayRole:
- return object->textRepresentation();
+ 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 {};
}
}
-/**
- * @brief Finds the position of the specified object in the model
- * @param id Object id to look for
- * @return model index
- */
-QModelIndex Model::find(ldraw::id_t id) const
+const ModelElement &Model::operator[](int index) const
+{
+ return this->body[index].data;
+}
+
+int Model::size() const
{
- if (this->needObjectsByIdRebuild)
- {
- this->objectsById.clear();
- for (std::size_t i = 0; i < this->body.size(); ++i)
- {
- this->objectsById[this->body[i]->id] = i;
- }
- this->needObjectsByIdRebuild = false;
- }
- const auto it = this->objectsById.find(id);
- if (it != this->objectsById.end())
- {
- return this->index(it->second);
- }
- else
- {
- return {};
+ 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 Gets an object id by position in the model
- * @param index Position of the object in the model
- * @return id
- */
-ldraw::id_t Model::idAt(const QModelIndex& index) const
-{
- return (*this)[index.row()]->id;
-}
-
-#if 0
-/**
* @brief Sets the path to the model
* @param path New path to use
*/
-void Model::setPath(const QString &path)
+void updateHeaderNameField(Model& model, const QString &name)
{
- this->storedPath = path;
- this->header.name = QFileInfo{path}.fileName();
// Update the "Name: 1234.dat" comment
- if (this->body.size() >= 2)
- {
- const ldraw::id_t id = this->body[1]->id;
- if (this->isA(id))
- {
- const QString& textBody = this->body[1]->getProperty();
- if (textBody.startsWith("Name: "))
- {
- auto editor = this->edit();
- editor.setObjectProperty(id, "Name: " + this->header.name);
+ if (model.size() >= 2) {
+ if (const Comment* nameObject = std::get_if(&model[1])) {
+ if (nameObject->text.startsWith("Name: ")) {
+ model[1] = Comment{"Name: " + name};
}
}
}
}
-#endif
-
-/**
- * @brief Adds the given object into the model.
- * @param object r-value reference to the object
- */
-ldraw::id_t Model::append(ModelObjectPointer&& object)
-{
- const int position = static_cast(this->body.size());
- Q_EMIT this->beginInsertRows({}, position, position);
- this->body.push_back(std::move(object));
- Q_EMIT this->endInsertRows();
- const ldraw::id_t id = this->body.back()->id;
- this->objectsById[id] = this->body.size() - 1;
- return id;
-}
-
-/**
- * @brief Removes the object at the specified position
- * @param position
- */
-void Model::remove(int position)
-{
- if (position >= 0 and position < signed_cast(this->body.size()))
- {
- Q_EMIT this->beginRemoveRows({}, position, position);
- this->body.erase(std::begin(this->body) + position);
- this->needObjectsByIdRebuild = true;
- Q_EMIT this->endRemoveRows();
- }
-}
-
-void Model::emitDataChangedSignal(int position)
-{
- Q_EMIT this->dataChanged(this->index(position), this->index(position));
-}
-
-/**
- * @brief Gets the object pointer at the specified position
- * @param index Position of the object
- * @returns object pointer
- */
-ldraw::Object* Model::operator[](int index)
-{
- if (index >= 0 and index < this->size())
- {
- return this->body[index].get();
- }
- else
- {
- throw std::out_of_range{"index out of range"};
- }
-}
-
-/**
- * @brief Gets the object pointer at the specified position
- * @param index Position of the object
- * @returns object pointer
- */
-const ldraw::Object* Model::operator[](int index) const
-{
- if (index >= 0 and index < this->size())
- {
- return this->body[index].get();
- }
- else
- {
- throw std::out_of_range{"index out of range"};
- }
-}
-
-/**
- * @brief Gets an object pointer by id. Used by the editing context to actually modify objects.
- * @param id
- * @return object pointer
- */
-ldraw::Object* Model::findObjectById(const ldraw::id_t id)
-{
- const QModelIndex index = this->find(id);
- if (index.isValid())
- {
- return (*this)[index.row()];
- }
- else
- {
- return nullptr;
- }
-}
-
-const ldraw::Object* Model::findObjectById(const ldraw::id_t id) const
-{
- const QModelIndex index = this->find(id);
- if (index.isValid())
- {
- return (*this)[index.row()];
- }
- else
- {
- return nullptr;
- }
-}
-
-/**
- * @brief Attempts the save the model
- */
-void save(const Model &model, QIODevice *device)
-{
- QTextStream out{device};
- applyToModel(model, [&](const ldraw::Object* object) {
- out << object->toLDrawCode() << "\r\n";
- });
-}