1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#ifndef __UNDO_H
#define __UNDO_H
#include <bsd/sys/queue.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <Scintilla.h>
#ifdef DEBUG
#include "parser.h"
#endif
class UndoToken {
public:
SLIST_ENTRY(UndoToken) tokens;
gint pos;
virtual void run() = 0;
};
class UndoTokenMessage : public UndoToken {
unsigned int iMessage;
uptr_t wParam;
sptr_t lParam;
public:
UndoTokenMessage(unsigned int _iMessage,
uptr_t _wParam = 0, sptr_t _lParam = 0)
: UndoToken(), iMessage(_iMessage),
wParam(_wParam), lParam(_lParam) {}
void run(void);
};
template <typename Type>
class UndoTokenVariable : public UndoToken {
Type *ptr;
Type value;
public:
UndoTokenVariable(Type &variable, Type _value)
: UndoToken(), ptr(&variable), value(_value) {}
void
run(void)
{
#ifdef DEBUG
if ((State **)ptr == &States::current)
g_printf("undo state -> %p\n", (void *)value);
#endif
*ptr = value;
}
};
class UndoTokenString : public UndoToken {
gchar **ptr;
gchar *str;
public:
UndoTokenString(gchar *&variable, gchar *_str)
: UndoToken(), ptr(&variable)
{
str = _str ? g_strdup(_str) : NULL;
}
~UndoTokenString()
{
g_free(str);
}
void
run(void)
{
g_free(*ptr);
*ptr = str;
str = NULL;
}
};
extern class UndoStack {
SLIST_HEAD(Head, UndoToken) head;
public:
bool enabled;
UndoStack(bool _enabled = false) : enabled(_enabled)
{
SLIST_INIT(&head);
}
~UndoStack();
void push(UndoToken *token);
void push_msg(unsigned int iMessage,
uptr_t wParam = 0, sptr_t lParam = 0);
template <typename Type>
inline void
push_var(Type &variable, Type value)
{
push(new UndoTokenVariable<Type>(variable, value));
}
template <typename Type>
inline void
push_var(Type &variable)
{
push_var<Type>(variable, variable);
}
inline void
push_str(gchar *&variable, gchar *str)
{
push(new UndoTokenString(variable, str));
}
inline void
push_str(gchar *&variable)
{
push_str(variable, variable);
}
void pop(gint pos);
void clear(void);
} undo;
#endif
|