From 1b27a5820b3d93141c1dcc7d5eaea73e9c33ddee Mon Sep 17 00:00:00 2001 From: gustav_b Date: Thu, 29 Mar 2007 23:02:20 +0000 Subject: [PATCH] Notify UndoStackObservers on commited incomplete transactions and sp_document_{undo,redo}_clear, see #1684042. --- src/composite-undo-stack-observer.cpp | 24 ++++++++ src/composite-undo-stack-observer.h | 23 ++++++++ src/console-output-undo-observer.cpp | 12 ++++ src/console-output-undo-observer.h | 2 + src/document-undo.cpp | 10 +++- src/event-log.cpp | 85 ++++++++++++++++++--------- src/event-log.h | 15 +++-- src/undo-stack-observer.h | 11 ++++ 8 files changed, 147 insertions(+), 35 deletions(-) diff --git a/src/composite-undo-stack-observer.cpp b/src/composite-undo-stack-observer.cpp index 85d7aed13..03e4796bd 100644 --- a/src/composite-undo-stack-observer.cpp +++ b/src/composite-undo-stack-observer.cpp @@ -79,6 +79,30 @@ CompositeUndoStackObserver::notifyUndoCommitEvent(Event* log) this->_unlock(); } +void +CompositeUndoStackObserver::notifyClearUndoEvent() +{ + this->_lock(); + for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) { + if (!i->to_remove) { + i->issueClearUndo(); + } + } + this->_unlock(); +} + +void +CompositeUndoStackObserver::notifyClearRedoEvent() +{ + this->_lock(); + for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) { + if (!i->to_remove) { + i->issueClearRedo(); + } + } + this->_unlock(); +} + bool CompositeUndoStackObserver::_remove_one(UndoObserverRecordList& list, UndoStackObserver& o) { diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h index 7e45ccae4..e24561ace 100644 --- a/src/composite-undo-stack-observer.h +++ b/src/composite-undo-stack-observer.h @@ -85,6 +85,26 @@ public: 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; }; @@ -134,6 +154,9 @@ public: */ void notifyUndoCommitEvent(Event* log); + virtual void notifyClearUndoEvent(); + virtual void notifyClearRedoEvent(); + private: // Remove an observer from a given list bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec); diff --git a/src/console-output-undo-observer.cpp b/src/console-output-undo-observer.cpp index 7035e89fe..98e6c69a6 100644 --- a/src/console-output-undo-observer.cpp +++ b/src/console-output-undo-observer.cpp @@ -34,6 +34,18 @@ ConsoleOutputUndoObserver::notifyUndoCommitEvent(Event* log) //g_message("notifyUndoCommitEvent (sp_document_maybe_done) called; log=%p\n", log->event); } +void +ConsoleOutputUndoObserver::notifyClearUndoEvent() +{ + //g_message("notifyClearUndoEvent (sp_document_clear_undo) called); +} + +void +ConsoleOutputUndoObserver::notifyClearRedoEvent() +{ + //g_message("notifyClearRedoEvent (sp_document_clear_redo) called); +} + } /* diff --git a/src/console-output-undo-observer.h b/src/console-output-undo-observer.h index 32149c15d..b6fec7f32 100644 --- a/src/console-output-undo-observer.h +++ b/src/console-output-undo-observer.h @@ -25,6 +25,8 @@ public: void notifyUndoEvent(Event* log); void notifyRedoEvent(Event* log); void notifyUndoCommitEvent(Event* log); + void notifyClearUndoEvent(); + void notifyClearRedoEvent(); }; } diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 47d56ca66..f37b53f89 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -201,7 +201,9 @@ void finish_incomplete_transaction(SPDocument &doc) { g_warning ("Incomplete undo transaction:"); priv.partial = sp_repr_coalesce_log(priv.partial, log); sp_repr_debug_print_log(priv.partial); - priv.undo = g_slist_prepend(priv.undo, new Inkscape::Event(priv.partial)); + Inkscape::Event *event = new Inkscape::Event(priv.partial); + priv.undo = g_slist_prepend(priv.undo, event); + priv.undoStackObservers.notifyUndoCommitEvent(event); priv.partial = NULL; } } @@ -303,6 +305,9 @@ sp_document_redo (SPDocument *doc) void sp_document_clear_undo (SPDocument *doc) { + if (doc->priv->undo) + doc->priv->undoStackObservers.notifyClearUndoEvent(); + while (doc->priv->undo) { GSList *current; @@ -318,6 +323,9 @@ sp_document_clear_undo (SPDocument *doc) void sp_document_clear_redo (SPDocument *doc) { + if (doc->priv->redo) + doc->priv->undoStackObservers.notifyClearRedoEvent(); + while (doc->priv->redo) { GSList *current; diff --git a/src/event-log.cpp b/src/event-log.cpp index d6bc99bea..4ee65f3f8 100644 --- a/src/event-log.cpp +++ b/src/event-log.cpp @@ -2,7 +2,7 @@ * Author: * Gustav Broberg * - * Copyright (c) 2006 Authors + * Copyright (c) 2006, 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -155,34 +155,7 @@ EventLog::notifyRedoEvent(Event* log) void EventLog::notifyUndoCommitEvent(Event* log) { - // If we're not at the last event in list then erase the previously undone events - if ( _last_event != _curr_event ) { - - _last_event = _curr_event; - - if ( !_last_event->children().empty() ) { - _last_event = _last_event->children().begin(); - } else { - ++_last_event; - } - - while ( _last_event != _event_list_store->children().end() ) { - - if (_last_event->parent()) { - while ( _last_event != _last_event->parent()->children().end() ) { - _last_event = _event_list_store->erase(_last_event); - } - _last_event = _last_event->parent(); - - (*_last_event)[_columns.child_count] = _last_event->children().size() + 1; - - ++_last_event; - } else { - _last_event = _event_list_store->erase(_last_event); - } - - } - } + _clearRedo(); const unsigned int event_type = log->type; @@ -235,6 +208,20 @@ EventLog::notifyUndoCommitEvent(Event* log) updateUndoVerbs(); } +void +EventLog::notifyClearUndoEvent() +{ + _clearUndo(); + updateUndoVerbs(); +} + +void +EventLog::notifyClearRedoEvent() +{ + _clearRedo(); + updateUndoVerbs(); +} + void EventLog::connectWithDialog(Gtk::TreeView *event_list_view, CallbackMap *callback_connections) { @@ -324,8 +311,48 @@ EventLog::_getRedoEvent() const return redo_event; } +void +EventLog::_clearUndo() +{ + // TODO: Implement when needed +} + +void +EventLog::_clearRedo() +{ + if ( _last_event != _curr_event ) { + + _last_event = _curr_event; + + if ( !_last_event->children().empty() ) { + _last_event = _last_event->children().begin(); + } else { + ++_last_event; + } + + while ( _last_event != _event_list_store->children().end() ) { + + if (_last_event->parent()) { + while ( _last_event != _last_event->parent()->children().end() ) { + _last_event = _event_list_store->erase(_last_event); + } + _last_event = _last_event->parent(); + + (*_last_event)[_columns.child_count] = _last_event->children().size() + 1; + + ++_last_event; + } else { + _last_event = _event_list_store->erase(_last_event); + } + + } + + } } +} // namespace Inkscape + + /* Local Variables: mode:c++ diff --git a/src/event-log.h b/src/event-log.h index 02cfa4b9a..a618f0467 100644 --- a/src/event-log.h +++ b/src/event-log.h @@ -16,7 +16,7 @@ * Author: * Gustav Broberg * - * Copyright (c) 2006 Authors + * Copyright (c) 2006, 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -72,6 +72,8 @@ public: void notifyUndoEvent(Event *log); void notifyRedoEvent(Event *log); void notifyUndoCommitEvent(Event *log); + void notifyClearUndoEvent(); + void notifyClearRedoEvent(); /** * Accessor functions @@ -116,10 +118,6 @@ private: const EventModelColumns _columns; - /** - * Helper functions for initialization - */ - Glib::RefPtr _event_list_store; Glib::RefPtr _event_list_selection; Gtk::TreeView *_event_list_view; @@ -133,9 +131,16 @@ private: // Map of connections used to temporary block/unblock callbacks in a TreeView CallbackMap *_callback_connections; + /** + * Helper functions + */ + const_iterator _getUndoEvent() const; //< returns the current undoable event or NULL if none const_iterator _getRedoEvent() const; //< returns the current redoable event or NULL if none + void _clearUndo(); //< erase all previously commited events + void _clearRedo(); //< erase all previously undone events + // noncopyable, nonassignable EventLog(EventLog const &other); EventLog& operator=(EventLog const &other); diff --git a/src/undo-stack-observer.h b/src/undo-stack-observer.h index dbda2b980..5bf405f7f 100644 --- a/src/undo-stack-observer.h +++ b/src/undo-stack-observer.h @@ -59,6 +59,17 @@ public: * \param log Pointer to an Event describing the committed events. */ virtual void notifyUndoCommitEvent(Event* log) = 0; + + /** + * Triggered when the undo log is cleared. + */ + virtual void notifyClearUndoEvent() = 0; + + /** + * Triggered when the redo log is cleared. + */ + virtual void notifyClearRedoEvent() = 0; + }; } -- 2.30.2