diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index ddaac0b7afc5d468275997dd9d6488a11abb04bf..784324116d142a3706301ff40ff6f85ff213ad2f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -1226,6 +1226,7 @@ void Effect::doOnBeforeCommit() if (sp_lpe_item->getCurrentLPE() == this) { DocumentUndo::ScopedInsensitive _no_undo(sp_lpe_item->document); sp_lpe_item_update_patheffect(sp_lpe_item, false, true); + update_satellites(false); } _lpe_action = LPE_NONE; return; diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 0ac2efd05b6867c5c63ea23ada15e5444f90aa68..a074d45066a534662de01e50ed5533e18ab61c4d 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -48,8 +48,51 @@ #include "ui/shape-editor.h" #include "uri.h" +//undo / redo +#include "xml/node-observer.h" + /* LPEItem base class */ +/** + * Notifies the path manipulator when something changes the path being edited + * (e.g. undo / redo) + */ +class SPLPEItemObserver : public Inkscape::XML::NodeObserver { +public: + SPLPEItemObserver(SPLPEItem *lpeitem) + : _lpeitem(lpeitem) + , _node(lpeitem->getRepr()) + , _blocked(false) + { + Inkscape::GC::anchor(_node); + _node->addObserver(*this); + } + + ~SPLPEItemObserver() override { + _node->removeObserver(*this); + Inkscape::GC::release(_node); + } + void notifyAttributeChanged(Inkscape::XML::Node &node, GQuark attr, + Inkscape::Util::ptr_shared a, Inkscape::Util::ptr_shared b) override + { + // do nothing if blocked or not undo/redo + if (_blocked || _lpeitem->document->isSensitive() || _lpeitem->isOnClipboard()) return; + GQuark path_d = g_quark_from_static_string("d"); + if (attr == path_d) { + _blocked = true; + sp_lpe_item_update_patheffect(_lpeitem, true, true); + _lpeitem->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + _blocked = false; + } + } + void block() { _blocked = true; } + void unblock() { _blocked = false; } +private: + SPLPEItem *_lpeitem; + Inkscape::XML::Node *_node; + bool _blocked; +}; + static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force = false, bool is_clip_mask = false); @@ -76,6 +119,7 @@ SPLPEItem::SPLPEItem() , lpe_modified_connection_list(new std::list()) , current_path_effect(nullptr) , lpe_helperpaths() + , _observer(nullptr) { } @@ -85,10 +129,14 @@ void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr(SPAttr::INKSCAPE_PATH_EFFECT); SPItem::build(document, repr); + _observer = new SPLPEItemObserver(this); } void SPLPEItem::release() { // disconnect all modified listeners: + if (_observer) { + delete _observer; + } for (auto & mod_it : *this->lpe_modified_connection_list) { @@ -186,6 +234,7 @@ void SPLPEItem::modified(unsigned int flags) { } Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + _observer->block(); if (flags & SP_OBJECT_WRITE_EXT) { if ( hasPathEffect() ) { repr->setAttributeOrRemoveIfEmpty("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); @@ -195,7 +244,7 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape } SPItem::write(xml_doc, repr, flags); - + _observer->unblock(); return repr; } diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 9b040d69b1df115c707f4f046461300d51cee096..a5f5a6b392d97827ce3e464f5062cbbbedf7e703 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -24,6 +24,7 @@ class LivePathEffectObject; class SPCurve; class SPShape; class SPDesktop; +class SPLPEItemObserver; namespace Inkscape{ namespace Display { @@ -113,6 +114,9 @@ public: bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1, bool recursive = true); void editNextParamOncanvas(SPDesktop *dt); void update_satellites(bool updatelpe); + private: + friend class SPLPEItemObserver; + SPLPEItemObserver *_observer; }; void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name! void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable);