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 "undo-stack-observer.h"
19 #include <list>
21 namespace Inkscape {
23 namespace XML {
25 class Event;
27 }
29 /**
30 * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo
31 * system.
32 */
33 class CompositeUndoStackObserver : public UndoStackObserver {
34 public:
36 /**
37 * Structure for tracking UndoStackObservers.
38 */
39 struct UndoStackObserverRecord {
40 public:
41 /**
42 * Constructor.
43 *
44 * \param o Reference to the UndoStackObserver that this UndoStackObserverRecord
45 * will track.
46 */
47 UndoStackObserverRecord(UndoStackObserver& o) : to_remove(false), _observer(o) { }
48 bool to_remove;
50 /**
51 * Overloaded equality test operator to facilitate usage of STL find algorithms.
52 */
53 bool operator==(UndoStackObserverRecord const& _x) const
54 {
55 return &(this->_observer) == &(_x._observer);
56 }
58 /**
59 * Issue a redo event to the UndoStackObserver that is associated with this UndoStackObserverRecord.
60 *
61 * \param log The event log generated by the redo event.
62 */
63 void issueRedo(XML::Event* log)
64 {
65 this->_observer.notifyRedoEvent(log);
66 }
68 /**
69 * Issue an undo event to the UndoStackObserver that is associated with this
70 * UndoStackObserverRecord.
71 *
72 * \param log The event log generated by the undo event.
73 */
74 void issueUndo(XML::Event* log)
75 {
76 this->_observer.notifyUndoEvent(log);
77 }
79 /**
80 * Issues a committed event to the UndoStackObserver that is associated with this
81 * UndoStackObserverRecord.
82 *
83 * \param log The event log being committed to the undo stack.
84 */
85 void issueUndoCommit(XML::Event* log)
86 {
87 this->_observer.notifyUndoCommitEvent(log);
88 }
90 private:
91 UndoStackObserver& _observer;
92 };
94 /// A list of UndoStackObserverRecords, used to aggregate multiple UndoStackObservers.
95 typedef std::list< UndoStackObserverRecord > UndoObserverRecordList;
97 /**
98 * Constructor.
99 */
100 CompositeUndoStackObserver();
102 ~CompositeUndoStackObserver();
104 /**
105 * Add an UndoStackObserver.
106 *
107 * \param observer Reference to an UndoStackObserver to add.
108 */
109 void add(UndoStackObserver& observer);
111 /**
112 * Remove an UndoStackObserver.
113 *
114 * \param observer Reference to an UndoStackObserver to remove.
115 */
116 void remove(UndoStackObserver& observer);
118 /**
119 * Notify all registered UndoStackObservers of an undo event.
120 *
121 * \param log The event log generated by the undo event.
122 */
123 void notifyUndoEvent(XML::Event* log);
125 /**
126 * Notify all registered UndoStackObservers of a redo event.
127 *
128 * \param log The event log generated by the redo event.
129 */
130 void notifyRedoEvent(XML::Event* log);
132 /**
133 * Notify all registered UndoStackObservers of an event log being committed to the undo stack.
134 *
135 * \param log The event log being committed to the undo stack.
136 */
137 void notifyUndoCommitEvent(XML::Event* log);
139 private:
140 // Remove an observer from a given list
141 bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec);
143 // Mark an observer for removal from a given list
144 bool _mark_one(UndoObserverRecordList& list, UndoStackObserver& rec);
146 // Keep track of whether or not we are notifying observers
147 unsigned int _iterating;
149 // Observers in the active list
150 UndoObserverRecordList _active;
152 // Observers to be added
153 UndoObserverRecordList _pending;
155 // Prevents the observer vector from modifications during
156 // iteration through the vector
157 void _lock() { this->_iterating++; }
158 void _unlock();
159 };
161 }
163 #endif