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