Wed, 22 Sep 2021 13:28:53 +0300
Document model.h
/* * 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/>. */ #pragma once #include "main.h" #include "model.h" class AbstractHistoryEntry { public: virtual void undo(Model::EditContext& editContext) = 0; virtual void redo(Model::EditContext& editContext) = 0; }; class InsertHistoryEntry : public AbstractHistoryEntry { public: InsertHistoryEntry(int position, const QByteArray& state) : position{position}, state{state} {} void undo(Model::EditContext& editContext) override; void redo(Model::EditContext& editContext) override; protected: int position; QByteArray state; }; class DeleteHistoryEntry : public InsertHistoryEntry { public: void undo(Model::EditContext& editContext) override; void redo(Model::EditContext& editContext) override; }; class EditHistoryEntry : public AbstractHistoryEntry { public: EditHistoryEntry(int position, const QByteArray& stateBefore, const QByteArray& stateAfter) : position{position}, stateBefore{stateBefore}, stateAfter{stateAfter} {} void undo(Model::EditContext& editContext) override; void redo(Model::EditContext& editContext) override; private: int position; QByteArray stateBefore; QByteArray stateAfter; }; class EditHistory { public: using Changeset = std::vector<std::unique_ptr<AbstractHistoryEntry>>; EditHistory(); /** * @brief Adds a new entry into the edit history. Creates a new changeset if there is not one already open. * If behind in history, deletes all history entries in front. */ template<typename T, typename... Rs> void add(Rs&&... args) { if (not this->changesetOpen) { while (this->position < this->changesets.size()) { this->changesets.erase(this->changesets.end() - 1); } if (this->changesets.empty()) { this->changesets.emplace_back(); } this->changesetOpen = true; } this->changesets.back().emplace_back(args...); } void commit() { this->changesetOpen = false; this->position += 1; } private: std::vector<Changeset> changesets; std::size_t position = 0; bool changesetOpen = false; };