diff -r 03f8e6d42e13 -r 2f79053c2e9a src/modeleditor.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modeleditor.h Fri Mar 04 11:40:19 2022 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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 .
+ */
+
+#pragma once
+#include "model.h"
+
+/**
+ * @brief Provides an interface for editing a model such that signals are emitted for each edit done.
+ * User edits to models should always be done through this class.
+ */
+class ModelEditor : public QObject
+{
+ Q_OBJECT
+public:
+ ModelEditor(Model& model);
+ ~ModelEditor();
+ template
+ ldraw::Id append(Args&&... args);
+ ldraw::id_t append(std::unique_ptr&& object);
+ template
+ ldraw::Id insert(int position, Args&&... args);
+ void remove(int position);
+ template
+ void setObjectProperty(ldraw::id_t id, const ldraw::PropertyType& value);
+ auto setObjectProperty(ldraw::id_t id, ldraw::Property property, const QVariant& value)
+ -> ldraw::Object::SetPropertyResult;
+ void setObjectPoint(ldraw::id_t id, int pointId, const glm::vec3& value);
+ template
+ bool modifyObject(ldraw::Id id, Fn&& function);
+ template
+ bool modifyObjectAt(int position, Fn&& function);
+ const Model& model();
+Q_SIGNALS:
+ void objectAdded(int position);
+ void objectModified(int position);
+ void objectRemoved(ldraw::id_t id);
+private:
+ QSet modifiedObjects;
+ Model& storedModel;
+};
+
+template
+void ModelEditor::setObjectProperty(const ldraw::id_t id, const ldraw::PropertyType& value)
+{
+ this->modifyObject(id, [&](ldraw::Object* object){
+ object->setProperty(value);
+ });
+}
+
+template
+ldraw::Id ModelEditor::append(Args&&... args)
+{
+ return this->storedModel.append(args...);
+}
+
+template
+ldraw::Id ModelEditor::insert(int position, Args&&... args)
+{
+ return this->storedModel.insert(position, args...);
+}
+
+template
+bool ModelEditor::modifyObject(ldraw::Id id, Fn&& function)
+{
+ QModelIndex index = this->model().find(id);
+ return this->modifyObjectAt(index.row(), function);
+}
+
+template
+bool ModelEditor::modifyObjectAt(int position, Fn&& function)
+{
+ if (position >= 0 and position < this->model().size())
+ {
+ T* object = dynamic_cast(this->storedModel[position]);
+ if (object != nullptr)
+ {
+ Q_EMIT this->objectModified(position);
+ function(object);
+ return true;
+ }
+ }
+ return false;
+}
\ No newline at end of file