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