~inkscape.dev/inkscape/trunk

10692 by Jon A. Cruz
Documentation update pass.
1
/*
1 by mental
moving trunk for module inkscape
2
 * Heavily inspired by Inkscape::XML::CompositeNodeObserver.
3
 *
4
 * Authors:
5
 * David Yip <yipdw@rose-hulman.edu>
6
 *
7
 * Copyright (c) 2005 Authors
8
 *
9
 * Released under GNU GPL, read the file 'COPYING' for more information
10
 */
11
2696 by mental
add required includes for gcc 4.3 and fix a const issue -- patch #1675635
12
#include <algorithm>
1 by mental
moving trunk for module inkscape
13
14
#include "composite-undo-stack-observer.h"
15
#include "xml/event.h"
16
17
namespace Inkscape {
18
19
CompositeUndoStackObserver::CompositeUndoStackObserver() : _iterating(0) { }
20
CompositeUndoStackObserver::~CompositeUndoStackObserver() { }
21
22
void
23
CompositeUndoStackObserver::add(UndoStackObserver& observer)
24
{
25
	if (!this->_iterating) {
26
		this->_active.push_back(UndoStackObserverRecord(observer));
27
	} else {
28
		this->_pending.push_back(UndoStackObserverRecord(observer));
29
	}
30
}
31
32
void
33
CompositeUndoStackObserver::remove(UndoStackObserver& observer)
34
{
35
	if (!this->_iterating) {
36
		// logical-or operator short-circuits
37
		this->_remove_one(this->_active, observer) || this->_remove_one(this->_pending, observer);
38
	} else {
39
		this->_mark_one(this->_active, observer) || this->_mark_one(this->_pending, observer);
40
	}
41
}
42
43
void
1319 by dwyip
backed out Event -> XML::Event changes
44
CompositeUndoStackObserver::notifyUndoEvent(Event* log)
1 by mental
moving trunk for module inkscape
45
{
46
	this->_lock();
47
	for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) {
48
		if (!i->to_remove) {
49
			i->issueUndo(log);
50
		}
51
	}
52
	this->_unlock();
53
}
54
55
void
1319 by dwyip
backed out Event -> XML::Event changes
56
CompositeUndoStackObserver::notifyRedoEvent(Event* log)
1 by mental
moving trunk for module inkscape
57
{
58
59
	this->_lock();
60
	for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) {
61
		if (!i->to_remove) {
62
			i->issueRedo(log);
63
		}
64
	}
65
	this->_unlock();
66
}
67
68
void
1319 by dwyip
backed out Event -> XML::Event changes
69
CompositeUndoStackObserver::notifyUndoCommitEvent(Event* log)
1 by mental
moving trunk for module inkscape
70
{
71
	this->_lock();
72
	for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) {
73
		if (!i->to_remove) {
74
			i->issueUndoCommit(log);
75
		}
76
	}
77
	this->_unlock();
78
}
79
2780 by gustav_b
Notify UndoStackObservers on commited incomplete transactions and sp_document_{undo,redo}_clear,
80
void
81
CompositeUndoStackObserver::notifyClearUndoEvent()
82
{
83
	this->_lock();
84
	for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) {
85
		if (!i->to_remove) {
86
			i->issueClearUndo();
87
		}
88
	}
89
	this->_unlock();
90
}
91
92
void
93
CompositeUndoStackObserver::notifyClearRedoEvent()
94
{
95
	this->_lock();
96
	for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) {
97
		if (!i->to_remove) {
98
			i->issueClearRedo();
99
		}
100
	}
101
	this->_unlock();
102
}
103
1 by mental
moving trunk for module inkscape
104
bool
105
CompositeUndoStackObserver::_remove_one(UndoObserverRecordList& list, UndoStackObserver& o)
106
{
107
	UndoStackObserverRecord eq_comp(o);
108
109
	UndoObserverRecordList::iterator i = std::find_if(list.begin(), list.end(), std::bind1st(std::equal_to< UndoStackObserverRecord >(), eq_comp));
110
111
	if (i != list.end()) {
112
		list.erase(i);
113
		return true;
114
	} else {
115
		return false;
116
	}
117
}
118
119
bool
120
CompositeUndoStackObserver::_mark_one(UndoObserverRecordList& list, UndoStackObserver& o)
121
{
122
	UndoStackObserverRecord eq_comp(o);
123
124
	UndoObserverRecordList::iterator i = std::find_if(list.begin(), list.end(), std::bind1st(std::equal_to< UndoStackObserverRecord >(), eq_comp));
125
126
	if (i != list.end()) {
127
		(*i).to_remove = true;
128
		return true;
129
	} else {
130
		return false;
131
	}
132
}
133
134
void
135
CompositeUndoStackObserver::_unlock()
136
{
137
	if (!--this->_iterating) {
138
		// Remove marked observers
139
		UndoObserverRecordList::iterator i = this->_active.begin();
10721 by Kris
Various fixes: initialization, memory leak, wrong iterator usage
140
		for(; i != this->_active.begin(); ) {
1 by mental
moving trunk for module inkscape
141
			if (i->to_remove) {
10721 by Kris
Various fixes: initialization, memory leak, wrong iterator usage
142
				i = this->_active.erase(i);
143
			}
144
			else{
145
				++i;
1 by mental
moving trunk for module inkscape
146
			}
147
		}
148
149
		i = this->_pending.begin();
10721 by Kris
Various fixes: initialization, memory leak, wrong iterator usage
150
		for(; i != this->_pending.begin(); ) {
1 by mental
moving trunk for module inkscape
151
			if (i->to_remove) {
10721 by Kris
Various fixes: initialization, memory leak, wrong iterator usage
152
				i = this->_active.erase(i);
153
			}
154
			else {
155
				++i;
1 by mental
moving trunk for module inkscape
156
			}
157
		}
158
159
		// Merge pending and active
160
		this->_active.insert(this->_active.end(), this->_pending.begin(), this->_pending.end());
161
		this->_pending.clear();
162
	}
163
}
164
165
}