36 EventTracker<SimpleEvent<Event::XML> > tracker(
"begin-transaction");
38 g_assert(doc !=
nullptr);
49 EventTracker<SimpleEvent<Event::XML> > tracker(
"rollback");
51 g_assert(doc !=
nullptr);
62 EventTracker<SimpleEvent<Event::XML> > tracker(
"commit");
64 g_assert(doc !=
nullptr);
75 EventTracker<SimpleEvent<Event::XML> > tracker(
"commit");
77 g_assert(doc !=
nullptr);
87 static LogPerformer &instance() {
88 static LogPerformer singleton;
92 void notifyChildAdded(Node &
parent, Node &
child, Node *
ref)
override {
96 void notifyChildRemoved(Node &
parent, Node &
child, Node *)
override {
100 void notifyChildOrderChanged(Node &
parent, Node &
child,
101 Node *, Node *new_ref)
override
113 void notifyContentChanged(Node &
node,
120 void notifyElementNameChanged(Node&
node,
GQuark ,
GQuark new_value)
override
132 for (
Event const *action =
log ; action ; action = action->
next ) {
143 EventTracker<SimpleEvent<Event::XML> > tracker(
"undo-log");
147 g_assert(!
log->repr->document()->inTransaction());
157 observer.notifyChildRemoved(*this->
repr, *this->child, this->ref);
194 std::vector<Inkscape::XML::Event const *> r;
199 for (
auto reversed = r.rbegin(); reversed != r.rend(); ++reversed ) {
211 EventTracker<SimpleEvent<Event::XML> > tracker(
"replay-log");
214 if (
log->repr->document()) {
215 g_assert(!
log->repr->document()->inTransaction());
271 for ( action = b ; action->
next ; action = action->
next ) {
272 prev_ptr = &action->
next;
297template <
typename T>
struct ActionRelations;
300struct ActionRelations<
Inkscape::XML::EventAdd> {
305struct ActionRelations<
Inkscape::XML::EventDel> {
311 typedef typename ActionRelations<A>::Opposite Opposite;
312 Opposite *opposite=
dynamic_cast<Opposite *
>(action->next);
316 if (opposite->repr == action->repr &&
317 opposite->child == action->child &&
318 opposite->ref == action->ref ) {
336 return cancel_add_or_remove(
this);
340 return cancel_add_or_remove(
this);
348 if ( chg_attr->
repr == this->repr &&
349 chg_attr->
key == this->key )
352 this->oldval = chg_attr->
oldval;
355 this->next = chg_attr->
next;
368 if (chg_content->
repr == this->repr ) {
370 this->oldval = chg_content->
oldval;
373 this->next = chg_content->
next;
388 if (chg_order->
repr == this->repr &&
389 chg_order->
child == this->child ){
394 if ( chg_order->
oldref == this->newref ) {
404 this->oldref = chg_order->
oldref;
407 this->next = chg_order->
next;
419 if (next_chg_element_name && next_chg_element_name->repr == this->repr) {
421 this->old_name = next_chg_element_name->
old_name;
422 this->next = next_chg_element_name->next;
423 delete next_chg_element_name;
434 static LogPrinter &instance() {
435 static LogPrinter singleton;
439 static Glib::ustring node_to_string(Node
const &
node) {
441 char const *type_name=
nullptr;
444 type_name =
"Document";
447 type_name =
"Element";
453 type_name =
"Comment";
456 g_assert_not_reached();
466 snprintf(buffer, 40,
"0x%p", &
node);
473 static Glib::ustring ref_to_string(Node *
ref) {
475 return node_to_string(*
ref);
481 void notifyChildAdded(Node &
parent, Node &
child, Node *
ref)
override {
482 g_warning(
"Event: Added %s to %s after %s", node_to_string(
parent).c_str(), node_to_string(
child).c_str(), ref_to_string(
ref).c_str());
485 void notifyChildRemoved(Node &
parent, Node &
child, Node *)
override {
486 g_warning(
"Event: Removed %s from %s", node_to_string(
parent).c_str(), node_to_string(
child).c_str());
489 void notifyChildOrderChanged(Node &
parent, Node &
child,
490 Node *, Node *new_ref)
override
492 g_warning(
"Event: Moved %s after %s in %s", node_to_string(
child).c_str(), ref_to_string(new_ref).c_str(), node_to_string(
parent).c_str());
500 g_warning(
"Event: Set attribute %s to \"%s\" on %s", g_quark_to_string(
name), new_value.
pointer(), node_to_string(
node).c_str());
502 g_warning(
"Event: Unset attribute %s on %s", g_quark_to_string(
name), node_to_string(
node).c_str());
506 void notifyContentChanged(Node &
node,
511 g_warning(
"Event: Set content of %s to \"%s\"", node_to_string(
node).c_str(), new_value.
pointer());
513 g_warning(
"Event: Unset content of %s", node_to_string(
node).c_str());
517 void notifyElementNameChanged(Node&
node,
GQuark old_value,
GQuark new_value)
override
519 g_warning(
"Event: Changed name of %s from %s to %s\n",
520 node_to_string(
node).c_str(), g_quark_to_string(old_value), g_quark_to_string(new_value));
char const * pointer() const
Object representing child addition.
void _undoOne(NodeObserver &observer) const override
void _replayOne(NodeObserver &observer) const override
Event * _optimizeOne() override
Object representing attribute change.
Inkscape::Util::ptr_shared oldval
Value of the attribute before the change.
void _undoOne(NodeObserver &observer) const override
GQuark key
GQuark corresponding to the changed attribute's name.
Event * _optimizeOne() override
void _replayOne(NodeObserver &observer) const override
Object representing content change.
Inkscape::Util::ptr_shared oldval
Content of the node before the change.
void _undoOne(NodeObserver &observer) const override
Event * _optimizeOne() override
void _replayOne(NodeObserver &observer) const override
Object representing element name change.
void _replayOne(NodeObserver &observer) const override
void _undoOne(NodeObserver &observer) const override
Event * _optimizeOne() override
GQuark old_name
GQuark corresponding to the old element name.
Object representing child order change.
Node * oldref
The node after which the relocated node was in the sibling order before the change,...
Node * child
The node that was relocated in sibling order.
void _replayOne(NodeObserver &observer) const override
Event * _optimizeOne() override
void _undoOne(NodeObserver &observer) const override
Object representing child removal.
void _replayOne(NodeObserver &observer) const override
Event * _optimizeOne() override
void _undoOne(NodeObserver &observer) const override
Enumeration of all XML event types.
Event * optimizeOne()
If possible, combine this event with the next to reduce memory use.
Event * next
Pointer to the next event in the event chain.
Node * repr
Pointer to the node that was the object of the event.
Interface for XML node observers.
virtual void notifyElementNameChanged(Node &node, GQuark old_name, GQuark new_name)
Element name change callback.
virtual void notifyAttributeChanged(Node &node, GQuark name, Util::ptr_shared old_value, Util::ptr_shared new_value)
Attribute change callback.
virtual void notifyContentChanged(Node &node, Util::ptr_shared old_content, Util::ptr_shared new_content)
Content change callback.
virtual void notifyChildOrderChanged(Node &node, Node &child, Node *old_prev, Node *new_prev)
Child order change callback.
virtual void notifyChildRemoved(Node &node, Node &child, Node *prev)
Child removal callback.
virtual void notifyChildAdded(Node &node, Node &child, Node *prev)
Child addition callback.
Interface for refcounted XML nodes.
virtual void setCodeUnsafe(int code)=0
Set the integer GQuark code for the name of the node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual void setContent(char const *value)=0
Set the content of a text or comment node.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
virtual NodeType type() const =0
Get the type of the node.
NodeObserver const * observer
static char const *const parent
TODO: insert short description here.
void sp_repr_replay_log(Inkscape::XML::Event *log)
void sp_repr_debug_print_log(Inkscape::XML::Event const *log)
Inkscape::XML::Event * sp_repr_coalesce_log(Inkscape::XML::Event *a, Inkscape::XML::Event *b)
void sp_repr_free_log(Inkscape::XML::Event *log)
void sp_repr_undo_log(Inkscape::XML::Event *log)
Inkscape::XML::Event * sp_repr_commit_undoable(Inkscape::XML::Document *doc)
void sp_repr_commit(Inkscape::XML::Document *doc)
void sp_repr_rollback(Inkscape::XML::Document *doc)
void sp_repr_begin_transaction(Inkscape::XML::Document *doc)
Inkscape::XML::Node * node
void undo_log_to_observer(Event const *log, NodeObserver &observer)
@ DOCUMENT_NODE
Top-level document node. Do not confuse with the root node.
@ COMMENT_NODE
Comment node, e.g. <!– some comment –>.
@ ELEMENT_NODE
Regular element node, e.g. <group />.
@ TEXT_NODE
Text node, e.g. "Some text" in <group>Some text</group> is represented by a text node.
void replay_log_to_observer(Event const *log, NodeObserver &observer)
Helper class to stream background task notifications as a series of messages.
Interface for XML node observers.
static cairo_user_data_key_t key
Piecewise< SBasis > log(Interval in)
Interface for XML documents.
virtual Event * commitUndoable()=0
Commit a transaction and store the events for later use.
virtual void commit()=0
Commit a transaction and discard change data.
virtual void rollback()=0
Restore the state of the document prior to the transaction.
virtual void beginTransaction()=0
Begin a transaction and start recording changes.
Interface for XML documents.