Wed, 25 May 2022 17:24:51 +0300
made editing tools not a polymorphic class tree
136 | 1 | /* |
2 | * LDForge: LDraw parts authoring CAD | |
3 | * Copyright (C) 2013 - 2020 Teemu Piippo | |
4 | * | |
5 | * This program is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
133 | 19 | #pragma once |
20 | #include "main.h" | |
21 | #include "model.h" | |
22 | ||
152 | 23 | class ModelEditor; |
24 | ||
133 | 25 | class AbstractHistoryEntry |
26 | { | |
27 | public: | |
152 | 28 | virtual void undo(ModelEditor& editContext) = 0; |
29 | virtual void redo(ModelEditor& editContext) = 0; | |
133 | 30 | }; |
31 | ||
32 | class InsertHistoryEntry : public AbstractHistoryEntry | |
33 | { | |
34 | public: | |
136 | 35 | InsertHistoryEntry(int position, const QByteArray& state) : |
133 | 36 | position{position}, |
136 | 37 | state{state} {} |
152 | 38 | void undo(ModelEditor& editContext) override; |
39 | void redo(ModelEditor& editContext) override; | |
133 | 40 | protected: |
41 | int position; | |
136 | 42 | QByteArray state; |
133 | 43 | }; |
44 | ||
45 | class DeleteHistoryEntry : public InsertHistoryEntry | |
46 | { | |
47 | public: | |
152 | 48 | void undo(ModelEditor& editContext) override; |
49 | void redo(ModelEditor& editContext) override; | |
133 | 50 | }; |
51 | ||
52 | class EditHistoryEntry : public AbstractHistoryEntry | |
53 | { | |
54 | public: | |
136 | 55 | EditHistoryEntry(int position, const QByteArray& stateBefore, const QByteArray& stateAfter) : |
133 | 56 | position{position}, |
136 | 57 | stateBefore{stateBefore}, |
58 | stateAfter{stateAfter} {} | |
152 | 59 | void undo(ModelEditor& editContext) override; |
60 | void redo(ModelEditor& editContext) override; | |
133 | 61 | private: |
62 | int position; | |
136 | 63 | QByteArray stateBefore; |
64 | QByteArray stateAfter; | |
133 | 65 | }; |
66 | ||
67 | class EditHistory | |
68 | { | |
69 | public: | |
136 | 70 | using Changeset = std::vector<std::unique_ptr<AbstractHistoryEntry>>; |
133 | 71 | EditHistory(); |
136 | 72 | /** |
73 | * @brief Adds a new entry into the edit history. Creates a new changeset if there is not one already open. | |
74 | * If behind in history, deletes all history entries in front. | |
75 | */ | |
76 | template<typename T, typename... Rs> | |
77 | void add(Rs&&... args) | |
78 | { | |
79 | if (not this->changesetOpen) | |
80 | { | |
81 | while (this->position < this->changesets.size()) | |
82 | { | |
83 | this->changesets.erase(this->changesets.end() - 1); | |
84 | } | |
85 | if (this->changesets.empty()) | |
86 | { | |
87 | this->changesets.emplace_back(); | |
88 | } | |
89 | this->changesetOpen = true; | |
90 | } | |
91 | this->changesets.back().emplace_back(args...); | |
92 | } | |
93 | void commit() | |
94 | { | |
95 | this->changesetOpen = false; | |
96 | this->position += 1; | |
97 | } | |
98 | private: | |
99 | std::vector<Changeset> changesets; | |
100 | std::size_t position = 0; | |
101 | bool changesetOpen = false; | |
133 | 102 | }; |