Code

feMorphology filter primitive implementation
[inkscape.git] / src / document-undo.cpp
index 09bb4e85729da13d2927cbdc5ce37bde63e5841c..81125833110313c50b78793bbadecf8b6ee35dde 100644 (file)
@@ -7,6 +7,7 @@
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   MenTaLguY <mental@rydia.net>
  *
+ * Copyright (C) 2007  MenTaLguY <mental@rydia.net>
  * Copyright (C) 1999-2003 authors
  * Copyright (C) 2001-2002 Ximian, Inc.
  *
@@ -62,6 +63,7 @@
 #include "inkscape.h"
 #include "debug/event-tracker.h"
 #include "debug/simple-event.h"
+#include "debug/timestamp.h"
 #include "event.h"
 
 
  *   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) {
@@ -98,10 +100,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);
 
@@ -121,6 +130,38 @@ sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkO
        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<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
 sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int event_type,
                         Glib::ustring event_description)
@@ -129,6 +170,8 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
        g_assert (doc->priv != NULL);
        g_assert (doc->priv->sensitive);
 
+        Inkscape::Debug::EventTracker<CommitEvent> tracker(doc, key, event_type);
+
        doc->collectOrphans();
 
        sp_document_ensure_up_to_date (doc);
@@ -144,9 +187,8 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
        }
 
        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));
+                ((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);
@@ -184,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)
 {
@@ -215,6 +255,7 @@ sp_document_undo (SPDocument *doc)
        g_assert (doc->priv->sensitive);
 
        doc->priv->sensitive = FALSE;
+        doc->priv->seeking = true;
 
        doc->actionkey = NULL;
 
@@ -237,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();
@@ -259,6 +301,7 @@ sp_document_redo (SPDocument *doc)
        g_assert (doc->priv->sensitive);
 
        doc->priv->sensitive = FALSE;
+        doc->priv->seeking = true;
 
        doc->actionkey = NULL;
 
@@ -281,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();
@@ -291,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;
 
@@ -306,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;