diff --git a/src/document-undo.cpp b/src/document-undo.cpp
index f37b53f89c5d89c228d78dd5b9eb67c61aa3aeff..1559dc5ba6cb10945fcb6ddc8aa37d00c37441c3 100644 (file)
--- a/src/document-undo.cpp
+++ b/src/document-undo.cpp
-#define __SP_DOCUMENT_UNDO_C__
-
/** \file
* Undo/Redo stack implementation
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* MenTaLguY <mental@rydia.net>
/** \file
* Undo/Redo stack implementation
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* MenTaLguY <mental@rydia.net>
+ * Abhishek Sharma
*
* Copyright (C) 2007 MenTaLguY <mental@rydia.net>
* Copyright (C) 1999-2003 authors
*
* Copyright (C) 2007 MenTaLguY <mental@rydia.net>
* Copyright (C) 1999-2003 authors
* stack. Two methods exist to indicate that the given action is completed:
*
* \verbatim
* stack. Two methods exist to indicate that the given action is completed:
*
* \verbatim
- void sp_document_done (SPDocument *document);
- void sp_document_maybe_done (SPDocument *document, const unsigned char *key) \endverbatim
+ 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
* list afterwards. While the first method does an unconditional push,
*
* Both move the recent action list into the undo stack and clear the
* list afterwards. While the first method does an unconditional push,
#if HAVE_STDLIB_H
#endif
#if HAVE_STDLIB_H
#endif
+#include <string>
+#include <cstring>
#include "xml/repr.h"
#include "document-private.h"
#include "inkscape.h"
#include "xml/repr.h"
#include "document-private.h"
#include "inkscape.h"
+#include "document-undo.h"
#include "debug/event-tracker.h"
#include "debug/simple-event.h"
#include "debug/event-tracker.h"
#include "debug/simple-event.h"
+#include "debug/timestamp.h"
#include "event.h"
/*
* Undo & redo
*/
#include "event.h"
/*
* Undo & redo
*/
-/**
- * Set undo sensitivity.
- *
- * \note
- * Since undo sensitivity needs to be nested, setting undo sensitivity
- * should be done like this:
- *\verbatim
- 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, bool sensitive)
+
+void Inkscape::DocumentUndo::setUndoSensitive(SPDocument *doc, bool sensitive)
{
g_assert (doc != NULL);
g_assert (doc->priv != NULL);
{
g_assert (doc != NULL);
g_assert (doc->priv != NULL);
* the saved bools in a stack. Perhaps this is why the above solution is better.
*/
* the saved bools in a stack. Perhaps this is why the above solution is better.
*/
-bool sp_document_get_undo_sensitive(SPDocument const *document) {
+bool Inkscape::DocumentUndo::getUndoSensitive(SPDocument const *document) {
g_assert(document != NULL);
g_assert(document->priv != NULL);
return document->priv->sensitive;
}
g_assert(document != NULL);
g_assert(document->priv != NULL);
return document->priv->sensitive;
}
-void
-sp_document_done (SPDocument *doc, const unsigned int event_type, Glib::ustring event_description)
+void Inkscape::DocumentUndo::done(SPDocument *doc, const unsigned int event_type, Glib::ustring const &event_description)
{
{
- sp_document_maybe_done (doc, NULL, event_type, event_description);
+ maybeDone(doc, NULL, event_type, event_description);
}
}
-void
-sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base)
+void Inkscape::DocumentUndo::resetKey( Inkscape::Application * /*inkscape*/, SPDesktop * /*desktop*/, GtkObject *base )
{
{
- SPDocument *doc = (SPDocument *) base;
- doc->actionkey = NULL;
+ SPDocument *doc = reinterpret_cast<SPDocument *>(base);
+ doc->actionkey.clear();
}
}
-void
-sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int event_type,
- Glib::ustring event_description)
+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 Inkscape::DocumentUndo::maybeDone(SPDocument *doc, const gchar *key, const unsigned int event_type,
+ Glib::ustring const &event_description)
{
g_assert (doc != NULL);
g_assert (doc->priv != NULL);
g_assert (doc->priv->sensitive);
{
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();
doc->collectOrphans();
- sp_document_ensure_up_to_date (doc);
+ doc->ensureUpToDate();
- sp_document_clear_redo (doc);
+ DocumentUndo::clearRedo(doc);
Inkscape::XML::Event *log = sp_repr_coalesce_log (doc->priv->partial, sp_repr_commit_undoable (doc->rdoc));
doc->priv->partial = NULL;
Inkscape::XML::Event *log = sp_repr_coalesce_log (doc->priv->partial, sp_repr_commit_undoable (doc->rdoc));
doc->priv->partial = NULL;
@@ -151,10 +176,9 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
return;
}
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);
} else {
Inkscape::Event *event = new Inkscape::Event(log, event_type, event_description);
doc->priv->undo = g_slist_prepend (doc->priv->undo, event);
@@ -162,20 +186,21 @@ sp_document_maybe_done (SPDocument *doc, const gchar *key, const unsigned int ev
doc->priv->undoStackObservers.notifyUndoCommitEvent(event);
}
doc->priv->undoStackObservers.notifyUndoCommitEvent(event);
}
- doc->actionkey = key;
+ if ( key ) {
+ doc->actionkey = key;
+ } else {
+ doc->actionkey.clear();
+ }
doc->virgin = FALSE;
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();
}
sp_repr_begin_transaction (doc->rdoc);
doc->priv->commit_signal.emit();
}
-void
-sp_document_cancel (SPDocument *doc)
+void Inkscape::DocumentUndo::cancel(SPDocument *doc)
{
g_assert (doc != NULL);
g_assert (doc->priv != NULL);
{
g_assert (doc != NULL);
g_assert (doc->priv != NULL);
sp_repr_begin_transaction (doc->rdoc);
}
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) {
SPDocumentPrivate &priv=*doc.priv;
Inkscape::XML::Event *log=sp_repr_commit_undoable(doc.rdoc);
if (log || priv.partial) {
}
}
}
}
-}
-
-gboolean
-sp_document_undo (SPDocument *doc)
+gboolean Inkscape::DocumentUndo::undo(SPDocument *doc)
{
using Inkscape::Debug::EventTracker;
using Inkscape::Debug::SimpleEvent;
{
using Inkscape::Debug::EventTracker;
using Inkscape::Debug::SimpleEvent;
doc->priv->sensitive = FALSE;
doc->priv->seeking = true;
doc->priv->sensitive = FALSE;
doc->priv->seeking = true;
- doc->actionkey = NULL;
+ doc->actionkey.clear();
finish_incomplete_transaction(*doc);
finish_incomplete_transaction(*doc);
sp_repr_undo_log (log->event);
doc->priv->redo = g_slist_prepend (doc->priv->redo, log);
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;
doc->priv->undoStackObservers.notifyUndoEvent(log);
ret = TRUE;
return ret;
}
return ret;
}
-gboolean
-sp_document_redo (SPDocument *doc)
+gboolean Inkscape::DocumentUndo::redo(SPDocument *doc)
{
using Inkscape::Debug::EventTracker;
using Inkscape::Debug::SimpleEvent;
{
using Inkscape::Debug::EventTracker;
using Inkscape::Debug::SimpleEvent;
doc->priv->sensitive = FALSE;
doc->priv->seeking = true;
doc->priv->sensitive = FALSE;
doc->priv->seeking = true;
- doc->actionkey = NULL;
+ doc->actionkey.clear();
finish_incomplete_transaction(*doc);
finish_incomplete_transaction(*doc);
sp_repr_replay_log (log->event);
doc->priv->undo = g_slist_prepend (doc->priv->undo, 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;
doc->priv->undoStackObservers.notifyRedoEvent(log);
ret = TRUE;
return ret;
}
return ret;
}
-void
-sp_document_clear_undo (SPDocument *doc)
+void Inkscape::DocumentUndo::clearUndo(SPDocument *doc)
{
if (doc->priv->undo)
doc->priv->undoStackObservers.notifyClearUndoEvent();
{
if (doc->priv->undo)
doc->priv->undoStackObservers.notifyClearUndoEvent();
}
}
}
}
-void
-sp_document_clear_redo (SPDocument *doc)
+void Inkscape::DocumentUndo::clearRedo(SPDocument *doc)
{
if (doc->priv->redo)
doc->priv->undoStackObservers.notifyClearRedoEvent();
{
if (doc->priv->redo)
doc->priv->undoStackObservers.notifyClearRedoEvent();