forked from erak/glmixer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHistoryManager.cpp
319 lines (226 loc) · 8.39 KB
/
HistoryManager.cpp
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
#include "HistoryManager.moc"
#include <QtGlobal>
#include <QDebug>
#include <Source.h>
HistoryManager::Event::Event(QObject *o, QMetaMethod m, QVector< QVariantPair > args) : _object(o), _method(m), _iskey(false)
{
// convert the list of QVariant pairs into list of History Arguments
foreach ( const QVariantPair &a, args) {
// create pair of History Arguments as a Vector
QVector<GenericArgument> argument;
// set value only for valid QVariant
if (a.first.isValid()) {
argument.append( GenericArgument(a.first) );
argument.append( GenericArgument(a.second) );
// qDebug() << argument[BACKWARD] << argument[FORWARD];
} else {
// else create empty arguments
argument.append( GenericArgument() );
argument.append( GenericArgument() );
}
// append the history argument to the list (in order)
_arguments.append(argument);
}
// qDebug() << "Stored to " << _method.signature() << _arguments.size();
}
void HistoryManager::Event::invoke(HistoryManager::Direction dir) {
// qDebug() << "Invoke " << objectName() << signature() << _arguments.size() << " arguments : " << _arguments[0][dir] << _arguments[1][dir] << _arguments[2][dir] << _arguments[3][dir] << _arguments[4][dir];
// invoke the method with all arguments (including empty arguments)
_method.invoke(_object, Qt::QueuedConnection, _arguments[0][dir].argument(), _arguments[1][dir].argument(), _arguments[2][dir].argument(), _arguments[3][dir].argument(), _arguments[4][dir].argument(), _arguments[5][dir].argument(), _arguments[6][dir].argument() );
}
QString HistoryManager::Event::signature() const {
return _method.signature();
}
QString HistoryManager::Event::objectName() const {
return _object->objectName();
}
QString HistoryManager::Event::arguments(Direction dir) const {
QString args("");
foreach (QVector<GenericArgument> a, _arguments) {
args += " " + a[dir].string();
}
return args;
}
bool HistoryManager::Event::operator == ( const HistoryManager::Event & other ) const
{
return ( _method.methodIndex() == other._method.methodIndex() && _object == other._object);
}
bool HistoryManager::Event::operator != ( const HistoryManager::Event & other ) const
{
return ( _method.methodIndex() != other._method.methodIndex() || _object != other._object);
}
HistoryManager::HistoryManager(QObject *parent) : QObject(parent), _maximumSize(1000)
{
_current = _history.begin();
_timer.start();
}
HistoryManager::EventMap HistoryManager::events(HistoryManager::Direction dir) const {
HistoryManager::EventMap eventmap;
if (dir == HistoryManager::BACKWARD) {
EventMap::iterator i = (EventMap::iterator) _history.begin();
while ( i != _current ){
eventmap.insert(i.key(),i.value());
++i;
}
}
else {
}
return eventmap;
}
void HistoryManager::rememberEvent(QString signature, QVariantPair arg1, QVariantPair arg2, QVariantPair arg3, QVariantPair arg4, QVariantPair arg5, QVariantPair arg6, QVariantPair arg7)
{
QObject *sender_object = sender();
if (sender_object) {
// keep time of the event (only even numbers)
qint64 t = _timer.elapsed();
t += t%2;
// get meta object of the object sending this slot
QMetaObject *sender_metaobject = (QMetaObject *) sender_object->metaObject();
// get slot id
int methodId = sender_metaobject->indexOfSlot(qPrintable(signature));
// get the method of this meta class
QMetaMethod method = sender_metaobject->method( methodId );
// list of arguments
QVector< QVariantPair > arguments;
arguments << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7;
// create an object storing this method call
Event *newcall = new Event(sender_object, method, arguments );
// if current event is not the last in the history
// then remove all the remaining items
EventMap::iterator it = ++_current;
while ( it != _history.end() ){
delete it.value();
it = _history.erase(it);
}
// remember the event in the history
_current = _history.insert(t, newcall);
// qDebug() << "Stored " << t << sender_metaobject->className() << newcall->signature() << newcall->arguments();
// inform that history changed
emit changed();
}
}
void HistoryManager::clear()
{
// delete all objects
qDeleteAll(_history);
// empty the list
_history.clear();
// go to end
_current = _history.begin();
// inform that history changed
emit changed();
qDebug() << "HistoryManager " << _history.size() << " elements";
}
void HistoryManager::setCursorPosition(qint64 t)
{
}
void HistoryManager::setCursorNextPositionForward()
{
// ignore if no event
if (_history.empty())
return;
if ( _current != _history.end() ) {
// invoke the previous event
_current.value()->invoke(HistoryManager::FORWARD);
// move the cursor to the previous event
_current++;
}
// inform that history changed
emit changed();
}
void HistoryManager::setCursorNextPositionBackward()
{
// ignore if no event
if (_history.empty())
return;
if ( _current == _history.end() )
_current--;
if ( _current != _history.begin() ) {
// invoke the previous event
_current.value()->invoke(HistoryManager::BACKWARD);
// move the cursor to the previous event
_current--;
}
// inform that history changed
emit changed();
}
void HistoryManager::setCursorNextPosition(HistoryManager::Direction dir)
{
// Backward in time
if (dir == HistoryManager::BACKWARD) {
setCursorNextPositionBackward();
}
// Forward in time
else {
setCursorNextPositionForward();
}
}
int HistoryManager::maximumSize() const
{
return _maximumSize;
}
void HistoryManager::setMaximumSize(int max)
{
_maximumSize = max;
}
//void HistoryManager::undoAll()
//{
//// QMap<qint64, SourceSlotEvent *> temp(_sourceSlotEvents);
//// _sourceSlotEvents.clear();
//// QMap<qint64, SourceSlotEvent *>::const_iterator i = _sourceSlotEvents.constEnd();
//// --i;
//// while (i != _sourceSlotEvents.constBegin()) {
//// SourceSlotEvent *e = i.value();
//// e->invoke();
//// --i;
//// }
// QMapIterator<qint64, SourceMethodCall *> i(_sourceSlotEvents);
// i.toBack();
// while (i.hasPrevious()) {
// i.previous();
// i.value()->invoke();
// }
// clearAll();
//}
//void HistoryManager::executeAll()
//{
//// QMap<qint64, SourceSlotEvent *> temp(_sourceSlotEvents);
//// _sourceSlotEvents.clear();
// QMapIterator<qint64, SourceMethodCall *> i(_sourceSlotEvents);
// while (i.hasNext()) {
// i.next();
// i.value()->invoke();
// }
//// clearAll();
//}
// remove the top key event
// qint64 k = _keyEvents.pop();
// // find the action at the undo key
// QMultiMap<qint64, Event *>::iterator i = _eventHistory.find(k);
// // do the action of the given key
// qDebug() << "undo " << i.key() << i.value()->signature() << i.value()->arguments(HistoryManager::BACKWARD);
// i.value()->invoke(HistoryManager::BACKWARD);
// // increment the iterator
// _currentEvent = i++;
// // remove the remaining events in the map
// for (; i != _eventHistory.end(); i = _eventHistory.erase(i)) {
// qDebug() << "undo delete " << i.key() << i.value()->signature();
// delete i.value();
// }
// if ( i.key() == k) {
// qDebug() << "undo " << i.key() << i.value()->signature();
// i.value()->invoke(HistoryManager::BACKWARD);
// }
// else {
// // in the multimap, get the list of all events at the current (past) key
// QList<Event *> keyCalls = _eventHistory.values( _currentKey );
// foreach ( Event *call, keyCalls) {
// // if the new call is different from one of the previous events at the current key
// if ( *call != *newcall ) {
// // declare a new key event
// _currentKey = t;
// newcall->setKey(true);
// break;
// }
// }
// }