Code

Extensions. Notebooks now work with internal extensions.
[inkscape.git] / src / document-undo.cpp
index 0462ff374a175fccd94e959c4958d1cda9e82a4c..e63fe8a529c552e19f12a82419d4ef6a1635f8f1 100644 (file)
 #if HAVE_STDLIB_H
 #endif
 
+#include <string>
+#include <cstring>
 #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"
 
 
@@ -122,11 +125,42 @@ sp_document_done (SPDocument *doc, const unsigned int event_type, Glib::ustring
         sp_document_maybe_done (doc, NULL, event_type, event_description);
 }
 
-void
-sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base)
+void sp_document_reset_key( Inkscape::Application * /*inkscape*/, SPDesktop * /*desktop*/, GtkObject *base )
 {
-       SPDocument *doc = (SPDocument *) base;
-       doc->actionkey = NULL;
+    SPDocument *doc = reinterpret_cast<SPDocument *>(base);
+    doc->actionkey.clear();
+}
+
+namespace {
+
+using Inkscape::Debug::Event;
+using Inkscape::Debug::SimpleEvent;
+using Inkscape::Util::share_static_string;
+using Inkscape::Debug::timestamp;
+using Inkscape::Verb;
+
+typedef SimpleEvent<Event::INTERACTION> 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
@@ -136,6 +170,11 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
        g_assert (doc != NULL);
        g_assert (doc->priv != NULL);
        g_assert (doc->priv->sensitive);
+        if ( key && !*key ) {
+            g_warning("Blank undo key specified.");
+        }
+
+        Inkscape::Debug::EventTracker<CommitEvent> tracker(doc, key, event_type);
 
        doc->collectOrphans();
 
@@ -151,10 +190,9 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
                return;
        }
 
-       if (key && doc->actionkey && !strcmp (key, doc->actionkey) && doc->priv->undo) {
-                doc->priv->undo->data = 
-                    new Inkscape::Event(sp_repr_coalesce_log (((Inkscape::Event *)
-                                                               doc->priv->undo->data)->event, log));
+       if (key && !doc->actionkey.empty() && (doc->actionkey == key) && doc->priv->undo) {
+                ((Inkscape::Event *)doc->priv->undo->data)->event =
+                    sp_repr_coalesce_log (((Inkscape::Event *)doc->priv->undo->data)->event, log);
        } else {
                 Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description);
                 doc->priv->undo = g_slist_prepend (doc->priv->undo, event);
@@ -162,12 +200,14 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
                doc->priv->undoStackObservers.notifyUndoCommitEvent(event);
        }
 
-       doc->actionkey = key;
+        if ( key ) {
+            doc->actionkey = key;
+        } else {
+            doc->actionkey.clear();
+        }
 
        doc->virgin = FALSE;
-       if (!doc->rroot->attribute("sodipodi:modified")) {
-               doc->rroot->setAttribute("sodipodi:modified", "true");
-       }
+        doc->setModifiedSinceSave();
 
        sp_repr_begin_transaction (doc->rdoc);
 
@@ -192,22 +232,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)
 {
@@ -225,7 +263,7 @@ sp_document_undo (SPDocument *doc)
        doc->priv->sensitive = FALSE;
         doc->priv->seeking = true;
 
-       doc->actionkey = NULL;
+       doc->actionkey.clear();
 
        finish_incomplete_transaction(*doc);
 
@@ -235,7 +273,7 @@ sp_document_undo (SPDocument *doc)
                sp_repr_undo_log (log->event);
                doc->priv->redo = g_slist_prepend (doc->priv->redo, log);
 
-               doc->rroot->setAttribute("sodipodi:modified", "true");
+                doc->setModifiedSinceSave();
                 doc->priv->undoStackObservers.notifyUndoEvent(log);
 
                ret = TRUE;
@@ -271,7 +309,7 @@ sp_document_redo (SPDocument *doc)
        doc->priv->sensitive = FALSE;
         doc->priv->seeking = true;
 
-       doc->actionkey = NULL;
+       doc->actionkey.clear();
 
        finish_incomplete_transaction(*doc);
 
@@ -281,7 +319,7 @@ sp_document_redo (SPDocument *doc)
                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;
@@ -303,6 +341,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 +359,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;