Code

7750dc73c9799545bae904a93c61d35423ad3bf8
[inkscape.git] / src / jabber_whiteboard / undo-stack-observer.cpp
1 /**
2  * Undo / redo / undo log commit listener
3  *
4  * Authors:
5  * David Yip <yipdw@rose-hulman.edu>
6  *
7  * Copyright (c) 2005 Authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include "document.h"
13 #include "document-private.h"
15 #include "xml/event.h"
16 #include "xml/event-fns.h"
17 #include "undo-stack-observer.h"
19 #include "util/list.h"
20 #include "util/reverse-list.h"
22 #include "jabber_whiteboard/defines.h"
23 #include "jabber_whiteboard/session-manager.h"
24 #include "jabber_whiteboard/node-tracker.h"
25 #include "jabber_whiteboard/serializer.h"
26 #include "jabber_whiteboard/message-utilities.h"
27 #include "jabber_whiteboard/message-aggregator.h"
28 #include "jabber_whiteboard/message-tags.h"
31 #include <glibmm.h>
33 namespace Inkscape {
35 namespace Whiteboard {
37 UndoStackObserver::UndoStackObserver(SessionManager* sm) : _sm(sm), _undoSendEventLocks(0), _redoSendEventLocks(0), _undoCommitSendEventLocks(0) { 
38 }
40 UndoStackObserver::~UndoStackObserver() { }
42 void
43 UndoStackObserver::notifyUndoEvent(XML::Event* log)
44 {
45         if (this->_undoSendEventLocks == 0) {
46                 bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM);
47                 Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_UNDO, "");
48                 this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom);
49         }
51         // Retrieve and process added/deleted nodes in the undo log
52         // TODO: re-enable; right now it doesn't work because we can't recover the names
53         // of deleted nodes (although perhaps creating a subclass of XML::Event that stored
54         // names of serialized nodes along with all other Event information would fix this)
55         /*
56         KeyToNodeActionMap node_actions = this->_action_observer.getNodeActionMap();
57         this->_sm->node_tracker()->process(node_actions);
58         this->_action_observer.clearNodeBuffers();
59         */
60         
61 }
63 void
64 UndoStackObserver::notifyRedoEvent(XML::Event* log)
65 {
66         if (this->_redoSendEventLocks == 0) {
67                 bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM);
68                 Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_REDO, "");
69                 this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom);
70         }
72         // Retrieve and process added/deleted nodes in the redo log
73         /*
74         KeyToNodeActionMap node_actions = this->_action_observer.getNodeActionMap();
75         this->_sm->node_tracker()->process(node_actions);
76         this->_action_observer.clearNodeBuffers();
77         */
78 }
80 void
81 UndoStackObserver::notifyUndoCommitEvent(XML::Event* log)
82 {
83         if (this->_undoCommitSendEventLocks == 0) {
84                 this->_doAction(log);
85         }
86 }
88 void
89 UndoStackObserver::lockObserverFromSending(ObserverType type)
90 {
91         switch (type) {
92                 case UNDO_EVENT:
93                         ++this->_undoSendEventLocks;
94                         break;
95                 case REDO_EVENT:
96                         ++this->_redoSendEventLocks;
97                         break;
98                 case UNDO_COMMIT_EVENT:
99                         ++this->_undoCommitSendEventLocks;
100                         break;
101                 default:
102                         break;
103         }
106 void
107 UndoStackObserver::unlockObserverFromSending(ObserverType type)
109         switch(type) {
110                 case UNDO_EVENT:
111                         if (this->_undoSendEventLocks) {
112                                 --this->_undoSendEventLocks;
113                         }
114                         break;
115                 case REDO_EVENT:
116                         if (this->_redoSendEventLocks) {
117                                 --this->_redoSendEventLocks;
118                         }
119                         break;
120                 case UNDO_COMMIT_EVENT:
121                         if (this->_undoCommitSendEventLocks) {
122                                 --this->_undoCommitSendEventLocks;
123                         }
124                         break;
125                 default:
126                         break;
127         }
130 void
131 UndoStackObserver::_doAction(XML::Event* log)
133         if (this->_sm->serializer()) {
134                 bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM);
135                 XML::replay_log_to_observer(log, *this->_sm->serializer());
137                 this->_sm->serializer()->synthesizeChildNodeAddEvents();
139                 SerializedEventList& events = this->_sm->serializer()->getEventList();
141                 SerializedEventList::iterator i = events.begin();
142                 MessageAggregator& agg = MessageAggregator::instance();
143                 Glib::ustring msgbuf;
145                 while(i != events.end()) {
146                         while(agg.addOne(*i++, msgbuf)) {
147                                 if (i == events.end()) {
148                                         break;
149                                 }
150                         }
152                         if (i != events.end()) {
153                                 i--;
154                         }
156                         this->_sm->sendChange(msgbuf, CHANGE_REPEATABLE, "", chatroom);
157                         msgbuf.clear();
158                 }
160                 KeyToNodeActionList& node_actions = this->_sm->serializer()->getNodeTrackerActions();
161                 this->_sm->node_tracker()->process(node_actions);
162                 this->_sm->serializer()->reset();
163                 Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_COMMIT, "");
164                 this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom);
165         }
172 /*
173   Local Variables:
174   mode:c++
175   c-file-style:"stroustrup"
176   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
177   indent-tabs-mode:nil
178   fill-column:99
179   End:
180 */
181 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :