Tue, 01 Mar 2022 17:00:19 +0200
work on edit history
src/document.cpp | file | annotate | diff | comparison | revisions | |
src/document.h | file | annotate | diff | comparison | revisions | |
src/edithistory.cpp | file | annotate | diff | comparison | revisions | |
src/edithistory.h | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/main.h | file | annotate | diff | comparison | revisions | |
src/model.h | file | annotate | diff | comparison | revisions | |
src/modeleditcontext.cpp | file | annotate | diff | comparison | revisions | |
src/modeleditcontext.h | file | annotate | diff | comparison | revisions |
--- a/src/document.cpp Tue Nov 02 15:43:57 2021 +0200 +++ b/src/document.cpp Tue Mar 01 17:00:19 2022 +0200 @@ -97,6 +97,13 @@ { this->renderer->rebuildVertices(this); }); + connect(this->model, &Model::objectStateChanged, [&]( + ldraw::id_t id, + const QByteArray& stateBefore, + const QByteArray& stateAfter + ){ + this->editHistory.add(EditHistoryEntry{id, stateBefore, stateAfter}); + }); this->setCanvasOverpaintCallback([&](Canvas* canvas, QPainter* painter) { if (this->selectedTool != nullptr)
--- a/src/document.h Tue Nov 02 15:43:57 2021 +0200 +++ b/src/document.h Tue Mar 01 17:00:19 2022 +0200 @@ -71,5 +71,5 @@ /** * @brief History information of edits to this model */ - // EditHistory editHistory; + EditHistory editHistory; };
--- a/src/edithistory.cpp Tue Nov 02 15:43:57 2021 +0200 +++ b/src/edithistory.cpp Tue Mar 01 17:00:19 2022 +0200 @@ -46,10 +46,24 @@ void EditHistoryEntry::undo(Model::EditContext &editContext) { - + this->doUndoRedo(editContext, this->stateAfter); } void EditHistoryEntry::redo(Model::EditContext &editContext) { - + this->doUndoRedo(editContext, this->stateBefore); } + +void EditHistoryEntry::doUndoRedo(Model::EditContext &editContext, QByteArray &state) +{ + const ldraw::id_t id = editContext.resolve(this->position); + if (id != ldraw::NULL_ID) + { + QDataStream stream{&state, QIODevice::ReadOnly}; + editContext.deserialize(id, stream); + } +} + +AbstractHistoryEntry::~AbstractHistoryEntry() +{ +}
--- a/src/edithistory.h Tue Nov 02 15:43:57 2021 +0200 +++ b/src/edithistory.h Tue Mar 01 17:00:19 2022 +0200 @@ -23,6 +23,7 @@ class AbstractHistoryEntry { public: + virtual ~AbstractHistoryEntry(); virtual void undo(Model::EditContext& editContext) = 0; virtual void redo(Model::EditContext& editContext) = 0; }; @@ -57,6 +58,7 @@ void undo(Model::EditContext& editContext) override; void redo(Model::EditContext& editContext) override; private: + void doUndoRedo(Model::EditContext &editContext, QByteArray& state); int position; QByteArray stateBefore; QByteArray stateAfter; @@ -97,4 +99,4 @@ std::vector<Changeset> changesets; std::size_t position = 0; bool changesetOpen = false; -}; \ No newline at end of file +};
--- a/src/main.cpp Tue Nov 02 15:43:57 2021 +0200 +++ b/src/main.cpp Tue Mar 01 17:00:19 2022 +0200 @@ -29,14 +29,7 @@ QCoreApplication::setOrganizationDomain("hecknology.net"); ::qRegisterMetaTypeStreamOperators<Library>("Library"); ::qRegisterMetaTypeStreamOperators<Libraries>("Libraries"); - - glm::mat4 mat = glm::scale(glm::mat4{1}, {3, 3, 3}); - glm::vec4 x = {1,2,3,4}; - QApplication app{argc, argv}; - /* - QMessageBox::information(nullptr, "", QMetaType::typeName( qMetaTypeId<ldraw::Color>() )); - */ MainWindow mainwindow; mainwindow.show(); return app.exec();
--- a/src/main.h Tue Nov 02 15:43:57 2021 +0200 +++ b/src/main.h Tue Mar 01 17:00:19 2022 +0200 @@ -226,6 +226,21 @@ >{map}; } +template<typename K, typename V, typename Fn> +void mapapply(const QMap<K, V>& map, Fn fn) +{ + for ( + typename QMap<K, V>::const_iterator it = map.constBegin(); + it != map.constEnd(); + ++it + ) { + fn(it.key(), it.value()); + } +} + +#define MAP_PARMS(map) decltype(map)::key_type const& key, decltype(map)::mapped_type& value +#define MAP_CPARMS(map) decltype(map)::key_type const& key, decltype(map)::mapped_type const& value + template<typename T, typename IdentifierType> struct TypeValue {
--- a/src/model.h Tue Nov 02 15:43:57 2021 +0200 +++ b/src/model.h Tue Mar 01 17:00:19 2022 +0200 @@ -70,7 +70,7 @@ void makeUnofficial(); Q_SIGNALS: void objectAdded(ldraw::id_t id, int position); - void objectModified(ldraw::id_t id, int position); + void objectStateChanged(int position, const QByteArray& stateBefore, const QByteArray& stateAfter); private: using ModelObjectPointer = std::unique_ptr<ldraw::Object>; template<typename T, typename... Args> @@ -155,7 +155,7 @@ } template<typename T, typename... Args> -ldraw::Id<T> Model::append(Args&&... args) +T* Model::append(Args&&... args) { const int position = static_cast<int>(this->body.size()); Q_EMIT beginInsertRows({}, position, position); @@ -169,7 +169,7 @@ } template<typename T, typename... Args> -ldraw::Id<T> Model::insert(const std::size_t position, Args&&... args) +T* Model::insert(const std::size_t position, Args&&... args) { Q_EMIT beginInsertRows({}, position, position); this->body.insert(std::begin(this->body) + position, std::make_unique<T>(args...));
--- a/src/modeleditcontext.cpp Tue Nov 02 15:43:57 2021 +0200 +++ b/src/modeleditcontext.cpp Tue Mar 01 17:00:19 2022 +0200 @@ -25,12 +25,29 @@ { } +void Model::EditContext::markObjectAsModified(ldraw::id_t id, ldraw::Object *object) +{ + if (not this->modifiedObjects.contains(id)) + { + QDataStream stream{&this->modifiedObjects[id], QIODevice::WriteOnly}; + object->serialize(stream); + } +} + Model::EditContext::~EditContext() { - for (ldraw::id_t id : this->modifiedObjects) + mapapply(this->modifiedObjects, [&](MAP_CPARMS(this->modifiedObjects)) { - this->model().objectModified(id); - } + ldraw::Object* object = this->model().objectAt(key); + if (object != nullptr) + { + QByteArray newState; + QDataStream stream{&newState, QIODevice::WriteOnly}; + object->serialize(stream); + const int position = this->model().lookup(key).row(); + Q_EMIT this->model().objectStateChanged(position, value, newState); + } + }); this->model().editFinished(); } @@ -42,6 +59,19 @@ return id; } +void Model::EditContext::insertFromState(int position, QByteArray &state) +{ + int typeInteger; + QDataStream stream{&state, QIODevice::ReadOnly}; + stream >> typeInteger; + switch (static_cast<ldraw::Object::Type>(typeInteger)) + { + case ldraw::Object::Type::Empty: + this->storedModel.insert<ldraw::Empty>(position); + break; + } +} + void Model::EditContext::remove(int position) { this->model().remove(position); @@ -56,8 +86,8 @@ ldraw::Object* const object = this->model().objectAt(id); if (object != nullptr) { + this->markObjectAsModified(id, object); const ldraw::Object::SetPropertyResult result = object->setProperty(ldraw::PropertyKeyValue{property, value}); - modifiedObjects.insert(id); return result; } else @@ -71,8 +101,8 @@ ldraw::Object* object = this->model().objectAt(id); if (object != nullptr) { + this->markObjectAsModified(id, object); object->setProperty(ldraw::PropertyKeyValue{ldraw::pointProperty(pointId), QVariant::fromValue(value)}); - modifiedObjects.insert(id); } } @@ -82,10 +112,40 @@ if (it != this->model().objectsById.end()) { ldraw::Object* object = it->second; + this->markObjectAsModified(id, object); object->invert(); } } +void Model::EditContext::deserialize(ldraw::id_t id, QDataStream &stream) +{ + auto it = this->model().objectsById.find(id); + if (it != this->model().objectsById.end()) + { + ldraw::Object* object = it->second; + int typeInteger; + stream >> typeInteger; + const ldraw::Object::Type type = static_cast<ldraw::Object::Type>(typeInteger); + if (object->typeIdentifier() == type) + { + this->markObjectAsModified(id, object); + object->deserialize(stream); + } + } +} + +ldraw::id_t Model::EditContext::resolve(int position) const +{ + if (position >= 0 and position < this->storedModel.rowCount({})) + { + return this->storedModel.objectAt(this->storedModel.index(position))->id; + } + else + { + return ldraw::NULL_ID; + } +} + Model& Model::EditContext::model() { return this->storedModel;
--- a/src/modeleditcontext.h Tue Nov 02 15:43:57 2021 +0200 +++ b/src/modeleditcontext.h Tue Mar 01 17:00:19 2022 +0200 @@ -26,6 +26,7 @@ template<typename T, typename... Args> ldraw::Id<T> append(Args&&... args); ldraw::id_t append(std::unique_ptr<ldraw::Object>&& object); + void insertFromState(int position, QByteArray& state); template<typename T, typename... Args> ldraw::Id<T> insert(int position, Args&&... args); void remove(int position); @@ -35,11 +36,14 @@ -> ldraw::Object::SetPropertyResult; void setObjectPoint(ldraw::id_t id, int pointId, const glm::vec3& value); void invertObject(ldraw::id_t id); + void deserialize(ldraw::id_t id, QDataStream& stream); + ldraw::id_t resolve(int position) const; Model& model(); private: EditContext(Model& model); + void markObjectAsModified(ldraw::id_t id, ldraw::Object* object); friend class Model; - QSet<ldraw::id_t> modifiedObjects; + QMap<ldraw::id_t, QByteArray> modifiedObjects; Model& storedModel; }; @@ -49,8 +53,8 @@ ldraw::Object* object = this->model().objectAt(id); if (object != nullptr) { + this->markObjectAsModified(id, object); object->setProperty<Property>(value); - modifiedObjects.insert(id); } }