X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdocument-undo.cpp;h=ae1c82e71f4e4d2e02b4ab2e6e480599ac26096f;hb=e26eb76ff5b635a35a28dcdd43ae6cac742a1fc0;hp=f37a3fcafb9450b14de2bac28075782bbfe048b6;hpb=f951374eef04129c6a0d213e7ab4d9ed2095ca69;p=inkscape.git diff --git a/src/document-undo.cpp b/src/document-undo.cpp index f37a3fcaf..ae1c82e71 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -7,6 +7,7 @@ * Lauris Kaplinski * MenTaLguY * + * Copyright (C) 2007 MenTaLguY * Copyright (C) 1999-2003 authors * Copyright (C) 2001-2002 Ximian, Inc. * @@ -22,7 +23,7 @@ * stack. Two methods exist to indicate that the given action is completed: * * \verbatim - void sp_document_done (SPDocument *document) + void sp_document_done (SPDocument *document); void sp_document_maybe_done (SPDocument *document, const unsigned char *key) \endverbatim * * Both move the recent action list into the undo stack and clear the @@ -57,11 +58,15 @@ #if HAVE_STDLIB_H #endif +#include +#include #include "xml/repr.h" #include "document-private.h" #include "inkscape.h" #include "debug/event-tracker.h" #include "debug/simple-event.h" +#include "debug/timestamp.h" +#include "event.h" /* @@ -74,18 +79,18 @@ * Since undo sensitivity needs to be nested, setting undo sensitivity * should be done like this: *\verbatim - gboolean saved = sp_document_get_undo_sensitive(document); - sp_document_set_undo_sensitive(document, FALSE); + bool saved = sp_document_get_undo_sensitive(document); + sp_document_set_undo_sensitive(document, false); ... do stuff ... sp_document_set_undo_sensitive(document, saved); \endverbatim */ void -sp_document_set_undo_sensitive (SPDocument *doc, gboolean sensitive) +sp_document_set_undo_sensitive (SPDocument *doc, bool sensitive) { g_assert (doc != NULL); g_assert (doc->priv != NULL); - if ( !(sensitive) == !(doc->priv->sensitive) ) + if ( sensitive == doc->priv->sensitive ) return; if (sensitive) { @@ -97,10 +102,17 @@ sp_document_set_undo_sensitive (SPDocument *doc, gboolean sensitive) ); } - doc->priv->sensitive = !!sensitive; + doc->priv->sensitive = sensitive; } -gboolean sp_document_get_undo_sensitive(SPDocument const *document) { +/*TODO: Throughout the inkscape code tree set/get_undo_sensitive are used for + * as is shown above. Perhaps it makes sense to create new functions, + * undo_ignore, and undo_recall to replace the start and end parts of the above. + * The main complexity with this is that they have to nest, so you have to store + * the saved bools in a stack. Perhaps this is why the above solution is better. + */ + +bool sp_document_get_undo_sensitive(SPDocument const *document) { g_assert(document != NULL); g_assert(document->priv != NULL); @@ -108,25 +120,60 @@ gboolean sp_document_get_undo_sensitive(SPDocument const *document) { } void -sp_document_done (SPDocument *doc) +sp_document_done (SPDocument *doc, const unsigned int event_type, Glib::ustring event_description) { - sp_document_maybe_done (doc, NULL); + sp_document_maybe_done (doc, NULL, event_type, event_description); } void -sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base) +sp_document_reset_key (Inkscape::Application */*inkscape*/, SPDesktop */*desktop*/, GtkObject *base) { - SPDocument *doc = (SPDocument *) base; - doc->actionkey = NULL; + SPDocument *doc = (SPDocument *) base; + doc->actionkey = NULL; +} + +namespace { + +using Inkscape::Debug::Event; +using Inkscape::Debug::SimpleEvent; +using Inkscape::Util::share_static_string; +using Inkscape::Debug::timestamp; +using Inkscape::Verb; + +typedef SimpleEvent InteractionEvent; + +class CommitEvent : public InteractionEvent { +public: + + CommitEvent(SPDocument *doc, const gchar *key, const unsigned int type) + : InteractionEvent(share_static_string("commit")) + { + _addProperty(share_static_string("timestamp"), timestamp()); + gchar *serial = g_strdup_printf("%lu", doc->serial()); + _addProperty(share_static_string("document"), serial); + g_free(serial); + Verb *verb = Verb::get(type); + if (verb) { + _addProperty(share_static_string("context"), verb->get_id()); + } + if (key) { + _addProperty(share_static_string("merge-key"), key); + } + } +}; + } void -sp_document_maybe_done (SPDocument *doc, const gchar *key) +sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int event_type, + Glib::ustring event_description) { g_assert (doc != NULL); g_assert (doc->priv != NULL); g_assert (doc->priv->sensitive); + Inkscape::Debug::EventTracker tracker(doc, key, event_type); + doc->collectOrphans(); sp_document_ensure_up_to_date (doc); @@ -142,21 +189,23 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key) } if (key && doc->actionkey && !strcmp (key, doc->actionkey) && doc->priv->undo) { - doc->priv->undo->data = sp_repr_coalesce_log ((Inkscape::XML::Event *)doc->priv->undo->data, log); + ((Inkscape::Event *)doc->priv->undo->data)->event = + sp_repr_coalesce_log (((Inkscape::Event *)doc->priv->undo->data)->event, log); } else { - doc->priv->undo = g_slist_prepend (doc->priv->undo, log); + Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description); + doc->priv->undo = g_slist_prepend (doc->priv->undo, event); doc->priv->history_size++; - doc->priv->undoStackObservers.notifyUndoCommitEvent(log); + doc->priv->undoStackObservers.notifyUndoCommitEvent(event); } doc->actionkey = key; doc->virgin = FALSE; - if (!doc->rroot->attribute("sodipodi:modified")) { - doc->rroot->setAttribute("sodipodi:modified", "true"); - } + doc->setModifiedSinceSave(); sp_repr_begin_transaction (doc->rdoc); + + doc->priv->commit_signal.emit(); } void @@ -177,22 +226,20 @@ sp_document_cancel (SPDocument *doc) sp_repr_begin_transaction (doc->rdoc); } -namespace { - -void finish_incomplete_transaction(SPDocument &doc) { +static void finish_incomplete_transaction(SPDocument &doc) { SPDocumentPrivate &priv=*doc.priv; Inkscape::XML::Event *log=sp_repr_commit_undoable(doc.rdoc); if (log || priv.partial) { 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, 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; } } -} - gboolean sp_document_undo (SPDocument *doc) { @@ -208,19 +255,20 @@ sp_document_undo (SPDocument *doc) g_assert (doc->priv->sensitive); doc->priv->sensitive = FALSE; + doc->priv->seeking = true; doc->actionkey = NULL; finish_incomplete_transaction(*doc); if (doc->priv->undo) { - Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->undo->data; + Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data; doc->priv->undo = g_slist_remove (doc->priv->undo, log); - sp_repr_undo_log (log); + sp_repr_undo_log (log->event); doc->priv->redo = g_slist_prepend (doc->priv->redo, log); - doc->rroot->setAttribute("sodipodi:modified", "true"); - doc->priv->undoStackObservers.notifyUndoEvent(log); + doc->setModifiedSinceSave(); + doc->priv->undoStackObservers.notifyUndoEvent(log); ret = TRUE; } else { @@ -230,6 +278,7 @@ sp_document_undo (SPDocument *doc) sp_repr_begin_transaction (doc->rdoc); doc->priv->sensitive = TRUE; + doc->priv->seeking = false; if (ret) inkscape_external_change(); @@ -252,18 +301,19 @@ sp_document_redo (SPDocument *doc) g_assert (doc->priv->sensitive); doc->priv->sensitive = FALSE; + doc->priv->seeking = true; doc->actionkey = NULL; finish_incomplete_transaction(*doc); if (doc->priv->redo) { - Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->redo->data; + Inkscape::Event *log=(Inkscape::Event *)doc->priv->redo->data; doc->priv->redo = g_slist_remove (doc->priv->redo, log); - sp_repr_replay_log (log); + sp_repr_replay_log (log->event); doc->priv->undo = g_slist_prepend (doc->priv->undo, log); - doc->rroot->setAttribute("sodipodi:modified", "true"); + doc->setModifiedSinceSave(); doc->priv->undoStackObservers.notifyRedoEvent(log); ret = TRUE; @@ -274,6 +324,7 @@ sp_document_redo (SPDocument *doc) sp_repr_begin_transaction (doc->rdoc); doc->priv->sensitive = TRUE; + doc->priv->seeking = false; if (ret) inkscape_external_change(); @@ -284,6 +335,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; @@ -291,7 +345,7 @@ sp_document_clear_undo (SPDocument *doc) doc->priv->undo = current->next; doc->priv->history_size--; - sp_repr_free_log ((Inkscape::XML::Event *)current->data); + delete ((Inkscape::Event *) current->data); g_slist_free_1 (current); } } @@ -299,6 +353,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; @@ -306,7 +363,7 @@ sp_document_clear_redo (SPDocument *doc) doc->priv->redo = current->next; doc->priv->history_size--; - sp_repr_free_log ((Inkscape::XML::Event *)current->data); + delete ((Inkscape::Event *) current->data); g_slist_free_1 (current); } }