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