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 private:
89 UndoStackObserver& _observer;
90 };
92 /// A list of UndoStackObserverRecords, used to aggregate multiple UndoStackObservers.
93 typedef std::list< UndoStackObserverRecord, GC::Alloc< UndoStackObserverRecord, GC::MANUAL > > UndoObserverRecordList;
95 /**
96 * Constructor.
97 */
98 CompositeUndoStackObserver();
100 ~CompositeUndoStackObserver();
102 /**
103 * Add an UndoStackObserver.
104 *
105 * \param observer Reference to an UndoStackObserver to add.
106 */
107 void add(UndoStackObserver& observer);
109 /**
110 * Remove an UndoStackObserver.
111 *
112 * \param observer Reference to an UndoStackObserver to remove.
113 */
114 void remove(UndoStackObserver& observer);
116 /**
117 * Notify all registered UndoStackObservers of an undo event.
118 *
119 * \param log The event log generated by the undo event.
120 */
121 void notifyUndoEvent(Event* log);
123 /**
124 * Notify all registered UndoStackObservers of a redo event.
125 *
126 * \param log The event log generated by the redo event.
127 */
128 void notifyRedoEvent(Event* log);
130 /**
131 * Notify all registered UndoStackObservers of an event log being committed to the undo stack.
132 *
133 * \param log The event log being committed to the undo stack.
134 */
135 void notifyUndoCommitEvent(Event* log);
137 private:
138 // Remove an observer from a given list
139 bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec);
141 // Mark an observer for removal from a given list
142 bool _mark_one(UndoObserverRecordList& list, UndoStackObserver& rec);
144 // Keep track of whether or not we are notifying observers
145 unsigned int _iterating;
147 // Observers in the active list
148 UndoObserverRecordList _active;
150 // Observers to be added
151 UndoObserverRecordList _pending;
153 // Prevents the observer vector from modifications during
154 // iteration through the vector
155 void _lock() { this->_iterating++; }
156 void _unlock();
157 };
159 }
161 #endif