summaryrefslogtreecommitdiffstats
path: root/src/composite-undo-stack-observer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/composite-undo-stack-observer.h')
-rw-r--r--src/composite-undo-stack-observer.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h
new file mode 100644
index 0000000..daf73b9
--- /dev/null
+++ b/src/composite-undo-stack-observer.h
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Authors:
+ * David Yip <yipdw@rose-hulman.edu>
+ *
+ * Copyright (c) 2005 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifndef SEEN_COMPOSITE_UNDO_COMMIT_OBSERVER_H
+#define SEEN_COMPOSITE_UNDO_COMMIT_OBSERVER_H
+
+#include "inkgc/gc-alloc.h"
+#include "undo-stack-observer.h"
+
+#include <list>
+
+namespace Inkscape {
+
+struct Event;
+
+/**
+ * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo
+ * system.
+ *
+ * Heavily inspired by Inkscape::XML::CompositeNodeObserver.
+ */
+class CompositeUndoStackObserver : public UndoStackObserver {
+public:
+
+ /**
+ * Structure for tracking UndoStackObservers.
+ */
+ struct UndoStackObserverRecord {
+ public:
+ /**
+ * Constructor.
+ *
+ * \param o Reference to the UndoStackObserver that this UndoStackObserverRecord
+ * will track.
+ */
+ UndoStackObserverRecord(UndoStackObserver& o) : to_remove(false), _observer(o) { }
+ bool to_remove;
+
+ /**
+ * Overloaded equality test operator to facilitate usage of STL find algorithms.
+ */
+ bool operator==(UndoStackObserverRecord const& _x) const
+ {
+ return &(this->_observer) == &(_x._observer);
+ }
+
+ /**
+ * Issue a redo event to the UndoStackObserver that is associated with this UndoStackObserverRecord.
+ *
+ * \param log The event log generated by the redo event.
+ */
+ void issueRedo(Event* log)
+ {
+ this->_observer.notifyRedoEvent(log);
+ }
+
+ /**
+ * Issue an undo event to the UndoStackObserver that is associated with this
+ * UndoStackObserverRecord.
+ *
+ * \param log The event log generated by the undo event.
+ */
+ void issueUndo(Event* log)
+ {
+ this->_observer.notifyUndoEvent(log);
+ }
+
+ /**
+ * Issues a committed event to the UndoStackObserver that is associated with this
+ * UndoStackObserverRecord.
+ *
+ * \param log The event log being committed to the undo stack.
+ */
+ void issueUndoCommit(Event* log)
+ {
+ this->_observer.notifyUndoCommitEvent(log);
+ }
+
+ /**
+ * Issue a clear undo event to the UndoStackObserver
+ * that is associated with this
+ * UndoStackObserverRecord.
+ */
+ void issueClearUndo()
+ {
+ this->_observer.notifyClearUndoEvent();
+ }
+
+ /**
+ * Issue a clear redo event to the UndoStackObserver
+ * that is associated with this
+ * UndoStackObserverRecord.
+ */
+ void issueClearRedo()
+ {
+ this->_observer.notifyClearRedoEvent();
+ }
+
+ private:
+ UndoStackObserver& _observer;
+ };
+
+ /// A list of UndoStackObserverRecords, used to aggregate multiple UndoStackObservers.
+ typedef std::list< UndoStackObserverRecord, GC::Alloc< UndoStackObserverRecord, GC::MANUAL > > UndoObserverRecordList;
+
+ /**
+ * Constructor.
+ */
+ CompositeUndoStackObserver();
+
+ ~CompositeUndoStackObserver() override;
+
+ /**
+ * Add an UndoStackObserver.
+ *
+ * \param observer Reference to an UndoStackObserver to add.
+ */
+ void add(UndoStackObserver& observer);
+
+ /**
+ * Remove an UndoStackObserver.
+ *
+ * \param observer Reference to an UndoStackObserver to remove.
+ */
+ void remove(UndoStackObserver& observer);
+
+ /**
+ * Notify all registered UndoStackObservers of an undo event.
+ *
+ * \param log The event log generated by the undo event.
+ */
+ void notifyUndoEvent(Event* log) override;
+
+ /**
+ * Notify all registered UndoStackObservers of a redo event.
+ *
+ * \param log The event log generated by the redo event.
+ */
+ void notifyRedoEvent(Event* log) override;
+
+ /**
+ * Notify all registered UndoStackObservers of an event log being committed to the undo stack.
+ *
+ * \param log The event log being committed to the undo stack.
+ */
+ void notifyUndoCommitEvent(Event* log) override;
+
+ void notifyClearUndoEvent() override;
+ void notifyClearRedoEvent() override;
+
+private:
+ // Remove an observer from a given list
+ bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec);
+
+ // Mark an observer for removal from a given list
+ bool _mark_one(UndoObserverRecordList& list, UndoStackObserver& rec);
+
+ // Keep track of whether or not we are notifying observers
+ unsigned int _iterating;
+
+ // Observers in the active list
+ UndoObserverRecordList _active;
+
+ // Observers to be added
+ UndoObserverRecordList _pending;
+
+ // Prevents the observer vector from modifications during
+ // iteration through the vector
+ void _lock() { this->_iterating++; }
+ void _unlock();
+};
+
+}
+
+#endif // SEEN_COMPOSITE_UNDO_COMMIT_OBSERVER_H