aboutsummaryrefslogtreecommitdiffhomepage
path: root/undo.h
blob: 055fc3d7cb6101530db3f01936d877ed9e3d8bf0 (plain)
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
#ifndef __UNDO_H
#define __UNDO_H

#include <bsd/sys/queue.h>

#include <glib.h>
#include <glib/gprintf.h>

#include <Scintilla.h>

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)
	{
		*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