7
7
* Lauris Kaplinski <lauris@kaplinski.com>
8
8
* MenTaLguY <mental@rydia.net>
10
* Copyright (C) 2007 MenTaLguY <mental@rydia.net>
10
11
* Copyright (C) 1999-2003 authors
11
12
* Copyright (C) 2001-2002 Ximian, Inc.
22
23
* stack. Two methods exist to indicate that the given action is completed:
25
void sp_document_done (SPDocument *document)
26
void sp_document_done (SPDocument *document);
26
27
void sp_document_maybe_done (SPDocument *document, const unsigned char *key) \endverbatim
28
29
* Both move the recent action list into the undo stack and clear the
74
79
* Since undo sensitivity needs to be nested, setting undo sensitivity
75
80
* should be done like this:
77
gboolean saved = sp_document_get_undo_sensitive(document);
78
sp_document_set_undo_sensitive(document, FALSE);
82
bool saved = sp_document_get_undo_sensitive(document);
83
sp_document_set_undo_sensitive(document, false);
80
85
sp_document_set_undo_sensitive(document, saved); \endverbatim
83
sp_document_set_undo_sensitive (SPDocument *doc, gboolean sensitive)
88
sp_document_set_undo_sensitive (SPDocument *doc, bool sensitive)
85
90
g_assert (doc != NULL);
86
91
g_assert (doc->priv != NULL);
88
if ( !(sensitive) == !(doc->priv->sensitive) )
93
if ( sensitive == doc->priv->sensitive )
100
doc->priv->sensitive = !!sensitive;
105
doc->priv->sensitive = sensitive;
103
gboolean sp_document_get_undo_sensitive(SPDocument const *document) {
108
/*TODO: Throughout the inkscape code tree set/get_undo_sensitive are used for
109
* as is shown above. Perhaps it makes sense to create new functions,
110
* undo_ignore, and undo_recall to replace the start and end parts of the above.
111
* The main complexity with this is that they have to nest, so you have to store
112
* the saved bools in a stack. Perhaps this is why the above solution is better.
115
bool sp_document_get_undo_sensitive(SPDocument const *document) {
104
116
g_assert(document != NULL);
105
117
g_assert(document->priv != NULL);
111
sp_document_done (SPDocument *doc)
113
sp_document_maybe_done (doc, NULL);
117
sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base)
119
SPDocument *doc = (SPDocument *) base;
120
doc->actionkey = NULL;
124
sp_document_maybe_done (SPDocument *doc, const gchar *key)
123
sp_document_done (SPDocument *doc, const unsigned int event_type, Glib::ustring event_description)
125
sp_document_maybe_done (doc, NULL, event_type, event_description);
129
sp_document_reset_key (Inkscape::Application */*inkscape*/, SPDesktop */*desktop*/, GtkObject *base)
131
SPDocument *doc = (SPDocument *) base;
132
doc->actionkey = NULL;
137
using Inkscape::Debug::Event;
138
using Inkscape::Debug::SimpleEvent;
139
using Inkscape::Util::share_static_string;
140
using Inkscape::Debug::timestamp;
141
using Inkscape::Verb;
143
typedef SimpleEvent<Event::INTERACTION> InteractionEvent;
145
class CommitEvent : public InteractionEvent {
148
CommitEvent(SPDocument *doc, const gchar *key, const unsigned int type)
149
: InteractionEvent(share_static_string("commit"))
151
_addProperty(share_static_string("timestamp"), timestamp());
152
gchar *serial = g_strdup_printf("%lu", doc->serial());
153
_addProperty(share_static_string("document"), serial);
155
Verb *verb = Verb::get(type);
157
_addProperty(share_static_string("context"), verb->get_id());
160
_addProperty(share_static_string("merge-key"), key);
168
sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int event_type,
169
Glib::ustring event_description)
126
171
g_assert (doc != NULL);
127
172
g_assert (doc->priv != NULL);
128
173
g_assert (doc->priv->sensitive);
175
Inkscape::Debug::EventTracker<CommitEvent> tracker(doc, key, event_type);
130
177
doc->collectOrphans();
132
179
sp_document_ensure_up_to_date (doc);
144
191
if (key && doc->actionkey && !strcmp (key, doc->actionkey) && doc->priv->undo) {
145
doc->priv->undo->data = sp_repr_coalesce_log ((Inkscape::XML::Event *)doc->priv->undo->data, log);
192
((Inkscape::Event *)doc->priv->undo->data)->event =
193
sp_repr_coalesce_log (((Inkscape::Event *)doc->priv->undo->data)->event, log);
147
doc->priv->undo = g_slist_prepend (doc->priv->undo, log);
195
Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description);
196
doc->priv->undo = g_slist_prepend (doc->priv->undo, event);
148
197
doc->priv->history_size++;
149
doc->priv->undoStackObservers.notifyUndoCommitEvent(log);
198
doc->priv->undoStackObservers.notifyUndoCommitEvent(event);
152
201
doc->actionkey = key;
154
203
doc->virgin = FALSE;
155
if (!doc->rroot->attribute("sodipodi:modified")) {
156
doc->rroot->setAttribute("sodipodi:modified", "true");
204
doc->setModifiedSinceSave();
159
206
sp_repr_begin_transaction (doc->rdoc);
179
226
sp_repr_begin_transaction (doc->rdoc);
184
void finish_incomplete_transaction(SPDocument &doc) {
229
static void finish_incomplete_transaction(SPDocument &doc) {
185
230
SPDocumentPrivate &priv=*doc.priv;
186
231
Inkscape::XML::Event *log=sp_repr_commit_undoable(doc.rdoc);
187
232
if (log || priv.partial) {
188
233
g_warning ("Incomplete undo transaction:");
189
234
priv.partial = sp_repr_coalesce_log(priv.partial, log);
190
235
sp_repr_debug_print_log(priv.partial);
191
priv.undo = g_slist_prepend(priv.undo, priv.partial);
236
Inkscape::Event *event = new Inkscape::Event(priv.partial);
237
priv.undo = g_slist_prepend(priv.undo, event);
238
priv.undoStackObservers.notifyUndoCommitEvent(event);
192
239
priv.partial = NULL;
199
244
sp_document_undo (SPDocument *doc)
210
255
g_assert (doc->priv->sensitive);
212
257
doc->priv->sensitive = FALSE;
258
doc->priv->seeking = true;
214
260
doc->actionkey = NULL;
216
262
finish_incomplete_transaction(*doc);
218
264
if (doc->priv->undo) {
219
Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->undo->data;
265
Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data;
220
266
doc->priv->undo = g_slist_remove (doc->priv->undo, log);
221
sp_repr_undo_log (log);
267
sp_repr_undo_log (log->event);
222
268
doc->priv->redo = g_slist_prepend (doc->priv->redo, log);
224
doc->rroot->setAttribute("sodipodi:modified", "true");
225
doc->priv->undoStackObservers.notifyUndoEvent(log);
270
doc->setModifiedSinceSave();
271
doc->priv->undoStackObservers.notifyUndoEvent(log);
254
301
g_assert (doc->priv->sensitive);
256
303
doc->priv->sensitive = FALSE;
304
doc->priv->seeking = true;
258
306
doc->actionkey = NULL;
260
308
finish_incomplete_transaction(*doc);
262
310
if (doc->priv->redo) {
263
Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->redo->data;
311
Inkscape::Event *log=(Inkscape::Event *)doc->priv->redo->data;
264
312
doc->priv->redo = g_slist_remove (doc->priv->redo, log);
265
sp_repr_replay_log (log);
313
sp_repr_replay_log (log->event);
266
314
doc->priv->undo = g_slist_prepend (doc->priv->undo, log);
268
doc->rroot->setAttribute("sodipodi:modified", "true");
316
doc->setModifiedSinceSave();
269
317
doc->priv->undoStackObservers.notifyRedoEvent(log);
293
345
doc->priv->undo = current->next;
294
346
doc->priv->history_size--;
296
sp_repr_free_log ((Inkscape::XML::Event *)current->data);
348
delete ((Inkscape::Event *) current->data);
297
349
g_slist_free_1 (current);
308
363
doc->priv->redo = current->next;
309
364
doc->priv->history_size--;
311
sp_repr_free_log ((Inkscape::XML::Event *)current->data);
366
delete ((Inkscape::Event *) current->data);
312
367
g_slist_free_1 (current);