1 /**
2 * Aggregates undo stack observers for management and triggering in SPDocument
3 *
4 * Heavily inspired by Inkscape::XML::CompositeNodeObserver.
5 *
6 * Authors:
7 * David Yip <yipdw@rose-hulman.edu>
8 *
9 * Copyright (c) 2005 Authors
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
14 #ifndef __COMPOSITE_UNDO_COMMIT_OBSERVER_H__
15 #define __COMPOSITE_UNDO_COMMIT_OBSERVER_H__
17 #include "gc-alloc.h"
18 #include "gc-managed.h"
19 #include "undo-stack-observer.h"
21 #include <list>
23 namespace Inkscape {
25 class Event;
27 /**
28 * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo
29 * system.
30 */
31 class CompositeUndoStackObserver : public UndoStackObserver {
32 public:
34 /**
35 * Structure for tracking UndoStackObservers.
36 */
37 struct UndoStackObserverRecord {
38 public:
39 /**
40 * Constructor.
41 *
42 * \param o Reference to the UndoStackObserver that this UndoStackObserverRecord
43 * will track.
44 */
45 UndoStackObserverRecord(UndoStackObserver& o) : to_remove(false), _observer(o) { }
46 bool to_remove;
48 /**
49 * Overloaded equality test operator to facilitate usage of STL find algorithms.
50 */
51 bool operator==(UndoStackObserverRecord const& _x) const
52 {
53 return &(this->_observer) == &(_x._observer);
54 }
56 /**
57 * Issue a redo event to the UndoStackObserver that is associated with this UndoStackObserverRecord.
58 *
59 * \param log The event log generated by the redo event.
60 */
61 void issueRedo(Event* log)
62 {
63 this->_observer.notifyRedoEvent(log);
64 }
66 /**
67 * Issue an undo event to the UndoStackObserver that is associated with this
68 * UndoStackObserverRecord.
69 *
70 * \param log The event log generated by the undo event.
71 */
72 void issueUndo(Event* log)
73 {
74 this->_observer.notifyUndoEvent(log);
75 }
77 /**
78 * Issues a committed event to the UndoStackObserver that is associated with this
79 * UndoStackObserverRecord.
80 *
81 * \param log The event log being committed to the undo stack.
82 */
83 void issueUndoCommit(Event* log)
84 {
85 this->_observer.notifyUndoCommitEvent(log);
86 }
88 /**
89 * Issue a clear undo event to the UndoStackObserver
90 * that is associated with this
91 * UndoStackObserverRecord.
92 */
93 void issueClearUndo()
94 {
95 this->_observer.notifyClearUndoEvent();
96 }
98 /**
99 * Issue a clear redo event to the UndoStackObserver
100 * that is associated with this
101 * UndoStackObserverRecord.
102 */
103 void issueClearRedo()
104 {
105 this->_observer.notifyClearRedoEvent();
106 }
108 private:
109 UndoStackObserver& _observer;
110 };
112 /// A list of UndoStackObserverRecords, used to aggregate multiple UndoStackObservers.
113 typedef std::list< UndoStackObserverRecord, GC::Alloc< UndoStackObserverRecord, GC::MANUAL > > UndoObserverRecordList;
115 /**
116 * Constructor.
117 */
118 CompositeUndoStackObserver();
120 ~CompositeUndoStackObserver();
122 /**
123 * Add an UndoStackObserver.
124 *
125 * \param observer Reference to an UndoStackObserver to add.
126 */
127 void add(UndoStackObserver& observer);
129 /**
130 * Remove an UndoStackObserver.
131 *
132 * \param observer Reference to an UndoStackObserver to remove.
133 */
134 void remove(UndoStackObserver& observer);
136 /**
137 * Notify all registered UndoStackObservers of an undo event.
138 *
139 * \param log The event log generated by the undo event.
140 */
141 void notifyUndoEvent(Event* log);
143 /**
144 * Notify all registered UndoStackObservers of a redo event.
145 *
146 * \param log The event log generated by the redo event.
147 */
148 void notifyRedoEvent(Event* log);
150 /**
151 * Notify all registered UndoStackObservers of an event log being committed to the undo stack.
152 *
153 * \param log The event log being committed to the undo stack.
154 */
155 void notifyUndoCommitEvent(Event* log);
157 virtual void notifyClearUndoEvent();
158 virtual void notifyClearRedoEvent();
160 private:
161 // Remove an observer from a given list
162 bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec);
164 // Mark an observer for removal from a given list
165 bool _mark_one(UndoObserverRecordList& list, UndoStackObserver& rec);
167 // Keep track of whether or not we are notifying observers
168 unsigned int _iterating;
170 // Observers in the active list
171 UndoObserverRecordList _active;
173 // Observers to be added
174 UndoObserverRecordList _pending;
176 // Prevents the observer vector from modifications during
177 // iteration through the vector
178 void _lock() { this->_iterating++; }
179 void _unlock();
180 };
182 }
184 #endif