|
1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013 Santeri 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 |
|
19 #include "history.h" |
|
20 #include "ldtypes.h" |
|
21 #include "document.h" |
|
22 #include "misc.h" |
|
23 #include "gui.h" |
|
24 #include "gldraw.h" |
|
25 |
|
26 bool g_fullRefresh = false; |
|
27 |
|
28 // ============================================================================= |
|
29 // ----------------------------------------------------------------------------- |
|
30 History::History() : |
|
31 m_Position (-1) {} |
|
32 |
|
33 // ============================================================================= |
|
34 // ----------------------------------------------------------------------------- |
|
35 void History::undo() |
|
36 { if (m_changesets.isEmpty() || getPosition() == -1) |
|
37 return; |
|
38 |
|
39 const Changeset& set = getChangeset (getPosition()); |
|
40 g_fullRefresh = false; |
|
41 |
|
42 // Iterate the list in reverse and undo all actions |
|
43 for (auto it = set.end() - 1; it != set.begin(); --it) |
|
44 (*it)->undo(); |
|
45 |
|
46 decreasePosition(); |
|
47 |
|
48 if (!g_fullRefresh) |
|
49 g_win->refresh(); |
|
50 else |
|
51 g_win->doFullRefresh(); |
|
52 |
|
53 g_win->updateActions(); |
|
54 } |
|
55 |
|
56 // ============================================================================= |
|
57 // ----------------------------------------------------------------------------- |
|
58 void History::redo() |
|
59 { if (getPosition() == (long) m_changesets.size()) |
|
60 return; |
|
61 |
|
62 const Changeset& set = getChangeset (getPosition() + 1); |
|
63 g_fullRefresh = false; |
|
64 |
|
65 // Redo things - in the order as they were done in the first place |
|
66 for (const AbstractHistoryEntry* change : set) |
|
67 change->redo(); |
|
68 |
|
69 setPosition (getPosition() + 1); |
|
70 |
|
71 if (!g_fullRefresh) |
|
72 g_win->refresh(); |
|
73 else |
|
74 g_win->doFullRefresh(); |
|
75 |
|
76 g_win->updateActions(); |
|
77 } |
|
78 |
|
79 // ============================================================================= |
|
80 // ----------------------------------------------------------------------------- |
|
81 void History::clear() |
|
82 { for (Changeset set : m_changesets) |
|
83 for (AbstractHistoryEntry* change : set) |
|
84 delete change; |
|
85 |
|
86 m_changesets.clear(); |
|
87 } |
|
88 |
|
89 // ============================================================================= |
|
90 // ----------------------------------------------------------------------------- |
|
91 void History::addStep() |
|
92 { if (m_currentChangeset.isEmpty()) |
|
93 return; |
|
94 |
|
95 while (getPosition() < getSize() - 1) |
|
96 m_changesets.removeLast(); |
|
97 |
|
98 m_changesets << m_currentChangeset; |
|
99 m_currentChangeset.clear(); |
|
100 setPosition (getPosition() + 1); |
|
101 g_win->updateActions(); |
|
102 } |
|
103 |
|
104 // ============================================================================= |
|
105 // ----------------------------------------------------------------------------- |
|
106 void History::add (AbstractHistoryEntry* entry) |
|
107 { if (isIgnoring()) |
|
108 { delete entry; |
|
109 return; |
|
110 } |
|
111 |
|
112 entry->setParent (this); |
|
113 m_currentChangeset << entry; |
|
114 } |
|
115 |
|
116 // ============================================================================= |
|
117 // ----------------------------------------------------------------------------- |
|
118 void AddHistory::undo() const |
|
119 { LDDocument* f = getParent()->getFile(); |
|
120 LDObject* obj = f->getObject (getIndex()); |
|
121 f->forgetObject (obj); |
|
122 delete obj; |
|
123 |
|
124 g_fullRefresh = true; |
|
125 } |
|
126 |
|
127 // ============================================================================= |
|
128 // ----------------------------------------------------------------------------- |
|
129 void AddHistory::redo() const |
|
130 { LDDocument* f = getParent()->getFile(); |
|
131 LDObject* obj = parseLine (getCode()); |
|
132 f->insertObj (getIndex(), obj); |
|
133 g_win->R()->compileObject (obj); |
|
134 } |
|
135 |
|
136 // ============================================================================= |
|
137 // heh |
|
138 // ----------------------------------------------------------------------------- |
|
139 void DelHistory::undo() const |
|
140 { LDDocument* f = getParent()->getFile(); |
|
141 LDObject* obj = parseLine (getCode()); |
|
142 f->insertObj (getIndex(), obj); |
|
143 g_win->R()->compileObject (obj); |
|
144 } |
|
145 |
|
146 // ============================================================================= |
|
147 // ----------------------------------------------------------------------------- |
|
148 void DelHistory::redo() const |
|
149 { LDDocument* f = getParent()->getFile(); |
|
150 LDObject* obj = f->getObject (getIndex()); |
|
151 f->forgetObject (obj); |
|
152 delete obj; |
|
153 |
|
154 g_fullRefresh = true; |
|
155 } |
|
156 |
|
157 // ============================================================================= |
|
158 // ----------------------------------------------------------------------------- |
|
159 void EditHistory::undo() const |
|
160 { LDObject* obj = getCurrentDocument()->getObject (getIndex()); |
|
161 LDObject* newobj = parseLine (getOldCode()); |
|
162 obj->replace (newobj); |
|
163 g_win->R()->compileObject (newobj); |
|
164 } |
|
165 |
|
166 // ============================================================================= |
|
167 // ----------------------------------------------------------------------------- |
|
168 void EditHistory::redo() const |
|
169 { LDObject* obj = getCurrentDocument()->getObject (getIndex()); |
|
170 LDObject* newobj = parseLine (getNewCode()); |
|
171 obj->replace (newobj); |
|
172 g_win->R()->compileObject (newobj); |
|
173 } |
|
174 |
|
175 // ============================================================================= |
|
176 // ----------------------------------------------------------------------------- |
|
177 void SwapHistory::undo() const |
|
178 { LDObject::fromID (a)->swap (LDObject::fromID (b)); |
|
179 } |
|
180 |
|
181 void SwapHistory::redo() const |
|
182 { undo(); // :v |
|
183 } |