4
\brief wxvdigit - Undo/Redo functionality
6
This program is free software under the GNU General Public
7
License (>=v2). Read the file COPYING that comes with GRASS
10
(C) 2008-2010 by Martin Landa, and the GRASS development team
12
\author Martin Landa <landa.martin gmail.com>
19
\brief Undo/Redo changes in geometry
21
level=0 to revert all changes
23
\param level level for undo/redo
25
\return id of current chanset
28
int Digit::Undo(int level)
32
changesetLast = (int) changesets.size() - 1;
34
if (changesetLast < 0)
37
if (changesetCurrent == -2) { /* value uninitialized */
38
changesetCurrent = changesetLast;
41
if (level > 0 && changesetCurrent < 0) {
47
level = -(changesetLast + 1);
50
G_debug(2, "Digit.Undo(): changeset_last=%d, changeset_current=%d, level=%d",
51
changesetLast, changesetCurrent, level);
53
if (level < 0) { /* undo */
54
if (changesetCurrent + level < -1)
55
return changesetCurrent;
56
for (int changeset = changesetCurrent; changeset > changesetCurrent + level; --changeset) {
57
ApplyChangeset(changeset, true);
60
else if (level > 0) { /* redo */
61
if (changesetCurrent + level > (int) changesets.size())
62
return changesetCurrent;
63
for (int changeset = changesetCurrent; changeset < changesetCurrent + level; ++changeset) {
64
ApplyChangeset(changeset, false);
68
changesetCurrent += level;
70
G_debug(2, "Digit.Undo(): changeset_current=%d, changeset_last=%d, changeset_end=%d",
71
changesetCurrent, changesetLast, changesetEnd);
73
if (changesetCurrent == changesetEnd) {
74
changesetEnd = changesetLast;
78
return changesetCurrent;
82
\brief Apply changeset (undo/redo changeset)
84
\param changeset changeset id
85
\param undo if true -> undo otherwise redo
87
\return 1 changeset applied
88
\return 0 changeset not applied
91
int Digit::ApplyChangeset(int changeset, bool undo)
95
if (changeset < 0 || changeset > (int) changesets.size())
99
changesetEnd = changeset;
102
std::vector<action_meta> action = changesets[changeset];
103
for (std::vector<action_meta>::const_reverse_iterator i = action.rbegin(), e = action.rend();
108
if ((undo && type == ADD) ||
109
(!undo && type == DEL)) {
110
if (Vect_line_alive(display->mapInfo, line)) {
111
G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d -> deleted",
113
Vect_delete_line(display->mapInfo, line);
118
G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d dead",
119
changeset, (*i).line);
123
long offset = (*i).offset;
124
if (!Vect_line_alive(display->mapInfo, line)) {
125
G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> added",
127
if (Vect_restore_line(display->mapInfo, line, offset) < 0)
133
G_debug(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d alive",
143
\brief Add action to changeset
145
\param type action type (ADD, DEL)
150
int Digit::AddActionToChangeset(int changeset, Digit::action_type type, int line)
154
if (!display->mapInfo) {
155
display->DisplayMsg();
159
if (!Vect_line_alive(display->mapInfo, line)) {
160
// display->DeadLineMsg(line);
164
offset = Vect_get_line_offset(display->mapInfo, line);
166
action_meta data = { type, line, offset };
167
if (changesets.find(changeset) == changesets.end()) {
168
changesets[changeset] = std::vector<action_meta>();
169
changesetCurrent = changeset;
171
changesets[changeset].push_back(data);
172
G_debug (3, "Digit.AddActionToChangeset(): changeset=%d, type=%d, line=%d, offset=%ld",
173
changeset, type, line, offset);
179
\brief Free changeset structures
181
\param changeset changeset id
183
void Digit::FreeChangeset(int changeset)
185
if (changesets.find(changeset) == changesets.end())
188
std::vector<action_meta> action = changesets[changeset];
189
for (std::vector<action_meta>::iterator i = action.begin(), e = action.end();
198
\brief Remove action from changeset
200
\param changeset changeset id
201
\param type action type (ADD, DEL)
204
\return number of actions in changeset
207
int Digit::RemoveActionFromChangeset(int changeset, Digit::action_type type, int line)
209
if (changesets.find(changeset) == changesets.end())
212
std::vector<action_meta>& action = changesets[changeset];
213
for (std::vector<action_meta>::iterator i = action.begin(); i != action.end(); ++i) {
214
if ((*i).type == type && (*i).line == line) {
215
G_debug (3, "Digit.RemoveActionFromChangeset(): changeset=%d, type=%d, line=%d",
216
changeset, type, line);
221
return action.size();
225
\brief Get undo level (number of active changesets)
229
int Digit::GetUndoLevel()
231
return changesetCurrent;