From fccc92ec8b639f8188c6476a3b71050c0171f85d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 13 Jun 2022 19:28:51 +0200 Subject: [PATCH] ... --- src/document-undo.cpp | 57 +-- src/document-undo.h | 7 + src/document.cpp | 4 + src/document.h | 4 + src/live_effects/lpe-bspline.cpp | 3 - src/live_effects/lpe-fillet-chamfer.cpp | 7 +- src/live_effects/lpe-slice.cpp | 362 +++++++++--------- src/live_effects/lpe-slice.h | 3 +- src/live_effects/lpe-transform_2pts.cpp | 12 +- src/live_effects/parameter/bool.cpp | 3 +- src/live_effects/parameter/colorpicker.cpp | 3 +- src/live_effects/parameter/fontbutton.cpp | 3 +- src/live_effects/parameter/parameter.cpp | 10 +- src/live_effects/parameter/patharray.cpp | 15 +- src/live_effects/parameter/point.cpp | 3 +- src/live_effects/parameter/satellite.cpp | 2 +- src/live_effects/parameter/satellitearray.cpp | 14 +- src/live_effects/parameter/text.cpp | 3 +- .../parameter/transformedpoint.cpp | 3 +- src/live_effects/parameter/vector.cpp | 3 +- src/object/box3d-side.cpp | 1 - src/object/sp-ellipse.cpp | 6 +- src/object/sp-lpe-item.cpp | 5 - src/object/sp-rect.cpp | 7 +- src/object/sp-shape.cpp | 8 +- src/object/sp-shape.h | 2 +- src/object/sp-spiral.cpp | 6 +- src/object/sp-star.cpp | 6 +- src/ui/dialog/undo-history.cpp | 30 +- src/ui/widget/registered-widget.h | 18 +- 30 files changed, 291 insertions(+), 319 deletions(-) diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 46f88b6d0b..ebc40898d7 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -150,9 +150,9 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, // This is only used for output to debug log file (and not for undo). Inkscape::Debug::EventTracker tracker(doc, key, event_description.c_str(), icon_name.c_str()); - doc->collectOrphans(); + doc->collectOrphans(); - doc->ensureUpToDate(); + doc->ensureUpToDate(); DocumentUndo::clearRedo(doc); @@ -181,11 +181,18 @@ void Inkscape::DocumentUndo::maybeDone(SPDocument *doc, } doc->virgin = FALSE; - doc->setModifiedSinceSave(); + doc->setModifiedSinceSave(); + doc->doning = true; - sp_repr_begin_transaction (doc->rdoc); +} - doc->commit_signal.emit(); +void Inkscape::DocumentUndo::maybeDoneFinish(SPDocument *doc) +{ + if (doc->doning) { + sp_repr_begin_transaction (doc->getReprDoc()); + doc->commit_signal.emit(); + doc->doning = false; + } } void Inkscape::DocumentUndo::cancel(SPDocument *doc) @@ -221,8 +228,8 @@ void Inkscape::DocumentUndo::finish_incomplete_transaction(SPDocument &doc) { // Member function for friend access to SPDocument privates. void Inkscape::DocumentUndo::perform_document_update(SPDocument &doc) { - sp_repr_begin_transaction(doc.rdoc); doc.ensureUpToDate(); + sp_repr_begin_transaction(doc.rdoc); Inkscape::XML::Event *update_log=sp_repr_commit_undoable(doc.rdoc); doc.emitReconstructionFinish(); @@ -255,7 +262,8 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) doc->sensitive = FALSE; doc->seeking = true; - + doc->undoing = true; + doc->lastundoredo = true; doc->actionkey.clear(); finish_incomplete_transaction(*doc); @@ -268,19 +276,12 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) doc->redo.push_back(log); doc->setModifiedSinceSave(); + doc->lastundoredo = false; doc->undoStackObservers.notifyUndoEvent(log); ret = TRUE; } else { ret = FALSE; } - - sp_repr_begin_transaction (doc->rdoc); - - doc->sensitive = TRUE; - doc->seeking = false; - - if (ret) INKSCAPE.external_change(); - return ret; } @@ -298,7 +299,8 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) doc->sensitive = FALSE; doc->seeking = true; - + doc->redoing = true; + doc->lastundoredo = true; doc->actionkey.clear(); finish_incomplete_transaction(*doc); @@ -311,22 +313,29 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) doc->setModifiedSinceSave(); doc->undoStackObservers.notifyRedoEvent(log); + doc->lastundoredo = false; ret = TRUE; } else { ret = FALSE; } + return ret; +} - sp_repr_begin_transaction (doc->rdoc); - - doc->sensitive = TRUE; +void Inkscape::DocumentUndo::undoredoFinish(SPDocument *doc) +{ + if (doc->undoing || doc->redoing) { + sp_repr_begin_transaction (doc->getReprDoc()); + doc->sensitive = TRUE; doc->seeking = false; - - if (ret) { - INKSCAPE.external_change(); + if (doc->lastundoredo) { + INKSCAPE.external_change(); + if (doc->redoing) { doc->emitReconstructionFinish(); + } } - - return ret; + doc->redoing = false; + doc->undoing = false; + } } void Inkscape::DocumentUndo::clearUndo(SPDocument *doc) diff --git a/src/document-undo.h b/src/document-undo.h index 937fa8bd06..526e93a035 100644 --- a/src/document-undo.h +++ b/src/document-undo.h @@ -41,6 +41,8 @@ public: static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon); static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon); + + static void maybeDoneFinish(SPDocument *document); private: static void finish_incomplete_transaction(SPDocument &document); @@ -56,6 +58,8 @@ public: static gboolean redo(SPDocument *document); + static void undoredoFinish(SPDocument *doc); + /** * RAII-style mechanism for creating a temporary undo-insensitive context. * @@ -77,6 +81,9 @@ public: m_saved = getUndoSensitive(doc); setUndoSensitive(doc, false); } + void stop() { + setUndoSensitive(m_doc, m_saved); + } ~ScopedInsensitive() { setUndoSensitive(m_doc, m_saved); } }; }; diff --git a/src/document.cpp b/src/document.cpp index 8b1dd7b6d3..528923a40c 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -54,6 +54,8 @@ #include "profile-manager.h" #include "rdf.h" +#include "document-undo.h" + #include "actions/actions-edit-document.h" #include "actions/actions-undo-document.h" #include "actions/actions-pages.h" @@ -1402,6 +1404,8 @@ SPDocument::idle_handler() { bool status = !_updateDocument(0); // method TRUE if it does NOT need further modification, so invert if (!status) { + Inkscape::DocumentUndo::maybeDoneFinish(this); + Inkscape::DocumentUndo::undoredoFinish(this); modified_connection.disconnect(); } return status; diff --git a/src/document.h b/src/document.h index 9332692ffd..f8589e02e4 100644 --- a/src/document.h +++ b/src/document.h @@ -434,6 +434,10 @@ private: // XXX only for testing! Inkscape::ConsoleOutputUndoObserver console_output_undo_observer; + bool redoing = false; // Related to undo/redo + bool undoing = false; // Related to undo/redo + bool lastundoredo = false; // Related to undo/redo + bool doning = false; // Related to done/maybeDone on doc.undo bool seeking; // Related to undo/redo/unique id unsigned long _serial; // Unique document number (used by undo/redo). Glib::ustring actionkey; // Last action key, used to combine actions in undo. diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index ab4c971cc1..72bb3c6705 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -47,12 +47,10 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); - weight.param_set_undo(false); steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); - steps.param_set_undo(false); helper_size.param_set_range(0.0, 999.0); helper_size.param_set_increments(1, 1); @@ -163,7 +161,6 @@ void LPEBSpline::toMakeCusp() void LPEBSpline::toWeight() { changeWeight(weight); - DocumentUndo::done(getSPDoc(), _("Change scalar parameter"), INKSCAPE_ICON("dialog-path-effects")); } void LPEBSpline::changeWeight(double weight_ammount) diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 2aa63fd253..2e518a5eff 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -84,7 +84,6 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) radius.param_set_range(0.0, std::numeric_limits::max()); radius.param_set_increments(1, 1); radius.param_set_digits(4); - radius.param_set_undo(false); chamfer_steps.param_set_range(1, std::numeric_limits::max()); chamfer_steps.param_set_increments(1, 1); chamfer_steps.param_make_integer(); @@ -373,8 +372,12 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) } // if are different sizes call to recalculate NodeSatellites nodesatellites = nodesatellites_param.data(); if (nodesatellites.empty()) { - doOnApply(lpeItem); // dont want _impl to not update versioning + nodesatellites_param.read_from_SVG(); nodesatellites = nodesatellites_param.data(); + if (nodesatellites.empty()) { + doOnApply(lpeItem); // dont want _impl to not update versioning + nodesatellites = nodesatellites_param.data(); + } } bool write = false; if (_pathvector_nodesatellites) { diff --git a/src/live_effects/lpe-slice.cpp b/src/live_effects/lpe-slice.cpp index 6fbf636f4c..6b5bb9bee5 100644 --- a/src/live_effects/lpe-slice.cpp +++ b/src/live_effects/lpe-slice.cpp @@ -241,170 +241,6 @@ LPESlice::originalDtoD(SPItem *item) } } -void -LPESlice::doAfterEffect (SPLPEItem const* lpeitem, SPCurve *curve) -{ - Glib::ustring version = lpeversion.param_getSVGValue(); - // this avoid regenerate fake satellites un undo after open a legacy LPE - if (!is_load && version < "1.2") { - return; - } - SPDocument *document = getSPDoc(); - if (!document) { - return; - } - bool m_saved = DocumentUndo::getUndoSensitive(getSPDoc()); - DocumentUndo::ScopedInsensitive _no_undo(document); - if (document->isPartial()) { - DocumentUndo::setUndoSensitive(document, m_saved); - } else if (document->isSeeking()) { - return; - } - bool is_applied_on = false; - if (is_applied) { - is_applied_on = true; - is_applied = false; - } - bool write = false; - bool active = !lpesatellites.data().size() || is_load; - for (auto const &lpereference : lpesatellites.data()) { - if (lpereference && lpereference->isAttached() && lpereference.get()->getObject() != nullptr) { - active = true; - } - } - if (!active && !is_load) { - lpesatellites.clear(); - return; - } - - LPESlice *nextslice = dynamic_cast(sp_lpe_item->getNextLPE(this)); - if (is_visible && (!nextslice || !nextslice->is_visible)) { - LPESlice *prevslice = dynamic_cast(sp_lpe_item->getPrevLPE(this)); - if (boundingbox_X.isSingular() || boundingbox_Y.isSingular()) { - for (auto & iter : lpesatellites.data()) { - SPObject *elemref; - if (iter && iter->isAttached() && (elemref = iter->getObject())) { - if (auto *splpeitem = dynamic_cast(elemref)) { - splpeitem->setHidden(true); - } - } - } - return; - } - //ungroup - if (!is_load && container && container != sp_lpe_item->parent && container != sp_lpe_item->parent->parent) { - processObjects(LPE_UPDATE); - } else if (!is_load && container && container != sp_lpe_item->parent) { // group - processObjects(LPE_UPDATE); - } - std::vector > slicer = getSplitLines(); - if (!slicer.size()) { - return; - } - container = lpeitem->parent; - objindex = 0; - legacy = false; - bool creation = write; - split(sp_lpe_item, curve, slicer, 0, creation); - bool connected = lpesatellites.is_connected(); - if (lpesatellites.data().size() && (creation || !connected)) { - lpesatellites.write_to_SVG(); - lpesatellites.start_listening(); - lpesatellites.update_satellites(!connected); - } - bool maindata = sp_has_path_data(sp_lpe_item, true); - for (auto & iter : lpesatellites.data()) { - SPObject *elemref; - if (iter && iter->isAttached() && (elemref = iter->getObject())) { - SPLPEItem *splpeitem = dynamic_cast(elemref); - if (splpeitem || lpeitem->isHidden()) { - if (!maindata || lpeitem->isHidden()) { - splpeitem->setHidden(true); - } - sp_lpe_item_update_patheffect(splpeitem, false, false); - } - } - } - if (!maindata) { - if (!curve) { // group - originalDtoD(sp_lpe_item); - } else { - originalDtoD(getCurrentShape(), curve); - } - return; - } - reset = false; - if (is_applied_on && prevslice) { - sp_lpe_item_update_patheffect(sp_lpe_item, false, false); - for (auto const &link : prevslice->lpesatellites.data()) { - if (link && link->isAttached()) { - SPGroup *spgrp = dynamic_cast(link->getObject()); - SPShape *spit = dynamic_cast(link->getObject()); - Glib::ustring transform = ""; - Glib::ustring patheffects = ""; - Geom::OptRect _gbbox = Geom::OptRect(); - if (spgrp) { - if (spgrp->getAttribute("transform")) { - transform = spgrp->getAttribute("transform"); - } - if (spgrp->getAttribute("inkscape:path-effect")) { - patheffects = spgrp->getAttribute("inkscape:path-effect"); - } - spgrp->setAttribute("transform", nullptr); - spgrp->setAttribute("inkscape:path-effect", nullptr); - _gbbox = spgrp->geometricBounds(); - } - if (spit || spgrp) { - for (auto const &link2 : lpesatellites.data()) { - if (link2 && link2->isAttached()) { - SPGroup *spgrp2 = dynamic_cast(link2->getObject()); - SPShape *spit2 = dynamic_cast(link2->getObject()); - if (spit && spit2) { - Geom::OptRect _bbox = spit->curveForEdit()->get_pathvector().boundsFast(); - Geom::OptRect _bbox2 = spit2->curveForEdit()->get_pathvector().boundsFast(); - if (_bbox && _bbox2) { - (*_bbox).expandBy(1); - if ((*_bbox).contains(*_bbox2)) { - spit2->setAttribute("transform", spit->getAttribute("transform")); - spit2->setAttribute("inkscape:path-effect", spit->getAttribute("inkscape:path-effect")); - spit2->setAttribute("style", spit->getAttribute("style")); - } - } - } else if (spgrp && spgrp2) { - Geom::OptRect _gbbox2 = spgrp2->geometricBounds(); - if (_gbbox && _gbbox2) { - (*_gbbox).expandBy(1); - if ((*_gbbox).contains(*_gbbox2)) { - spgrp2->setAttribute("transform", transform); - spgrp2->setAttribute("inkscape:path-effect", patheffects); - cloneStyle(spgrp, spgrp2); - } - } - } - } - } - if (spgrp) { - spgrp->setAttribute("transform", transform); - spgrp->setAttribute("inkscape:path-effect", patheffects); - } - } - } - } - - } - } else { - for (auto const &itemrf : lpesatellites.data()) { - if (itemrf && itemrf->isAttached()) { - SPLPEItem *splpeitem = dynamic_cast(itemrf->getObject()); - if (splpeitem) { - splpeitem->setHidden(true); - sp_lpe_item_update_patheffect(splpeitem, false, false); - } - } - } - } -} - bool LPESlice::split(SPItem* item, SPCurve *curve, std::vector > slicer, size_t splitindex, bool &creation) { bool splited = false; @@ -603,7 +439,7 @@ static fill_typ GetFillTyp(SPItem *item) } bool -LPESlice::splititem(SPItem* item, SPCurve * curve, std::pair slicer, bool toggle, bool is_original) +LPESlice::splititem(SPItem* item, SPCurve * curve, std::pair slicer, bool toggle, bool is_original, Geom::Affine tpass) { bool splited = false; if (!is_original && !g_strcmp0(sp_lpe_item->getId(), item->getId())) { @@ -615,14 +451,15 @@ LPESlice::splititem(SPItem* item, SPCurve * curve, std::pair Geom::Point center = Geom::middle_point(s, e); SPGroup *group = dynamic_cast(item); if (group) { + Geom::Affine t = group->transform * tpass; + if (!g_strcmp0(sp_lpe_item->getId(), item->getId())) { + t = Geom::identity(); + } std::vector childs = group->childList(true); for (auto &child : childs) { SPItem *dest_child = dynamic_cast(child); // groups not need update curve - splited = splititem(dest_child, nullptr, slicer, toggle, is_original) ? true : splited; - } - if (!is_original && group->hasPathEffectRecursive()) { - sp_lpe_item_update_patheffect(group, false, false); + splited = splititem(dest_child, nullptr, slicer, toggle, is_original, t) ? true : splited; } return splited; } @@ -635,7 +472,7 @@ LPESlice::splititem(SPItem* item, SPCurve * curve, std::pair Geom::PathVector original_pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); sp_flatten(original_pathv, GetFillTyp(shape)); Geom::PathVector path_out; - Geom::Affine t = shape->transform; + Geom::Affine t = shape->transform * tpass; if (!dynamic_cast(sp_lpe_item)) { t = Geom::identity(); } @@ -746,26 +583,18 @@ LPESlice::splititem(SPItem* item, SPCurve * curve, std::pair tmp_pathvector.clear(); } - if (curve && is_original) { - curve->set_pathvector(path_out); - } if (shape->curve()) { - shape->bbox_vis_cache_is_valid = false; - shape->bbox_geom_cache_is_valid = false; - shape->setCurveInsync(SPCurve(path_out)); + //sp_lpe_item_enable_path_effects(sp_lpe_item, false); auto str = sp_svg_write_path(path_out); - if (!is_original && shape->hasPathEffectRecursive()) { - sp_lpe_item_enable_path_effects(shape, false); - if (path) { - shape->setAttribute("inkscape:original-d", str); - } else { - shape->setAttribute("d", str); - } - sp_lpe_item_enable_path_effects(shape, true); + if (path && + g_strcmp0(sp_lpe_item->getId(), item->getId()) && + shape->hasPathEffectRecursive()) + { + shape->setAttribute("inkscape:original-d", str); } else { - shape->setAttribute("d", str); + shape->setCurveInsync(SPCurve(path_out)); } - } + } } } return splited; @@ -844,6 +673,159 @@ LPESlice::doBeforeEffect (SPLPEItem const* lpeitem) } } allow_transforms_prev = allow_transforms; + Glib::ustring version = lpeversion.param_getSVGValue(); + // this avoid regenerate fake satellites un undo after open a legacy LPE + if (!is_load && version < "1.2") { + return; + } + bool is_applied_on = false; + if (is_applied) { + is_applied_on = true; + is_applied = false; + } + bool write = false; + bool active = !lpesatellites.data().size() || is_load; + for (auto const &lpereference : lpesatellites.data()) { + if (lpereference && lpereference->isAttached() && lpereference.get()->getObject() != nullptr) { + active = true; + } + } + if (!active && !is_load) { + lpesatellites.clear(); + return; + } + + LPESlice *nextslice = dynamic_cast(sp_lpe_item->getNextLPE(this)); + if (is_visible && (!nextslice || !nextslice->is_visible)) { + LPESlice *prevslice = dynamic_cast(sp_lpe_item->getPrevLPE(this)); + if (boundingbox_X.isSingular() || boundingbox_Y.isSingular()) { + for (auto & iter : lpesatellites.data()) { + SPObject *elemref; + if (iter && iter->isAttached() && (elemref = iter->getObject())) { + if (auto *splpeitem = dynamic_cast(elemref)) { + splpeitem->setHidden(true); + } + } + } + return; + } + //ungroup + if (!is_load && container && container != sp_lpe_item->parent && container != sp_lpe_item->parent->parent) { + processObjects(LPE_UPDATE); + } else if (!is_load && container && container != sp_lpe_item->parent) { // group + processObjects(LPE_UPDATE); + } + std::vector > slicer = getSplitLines(); + if (!slicer.size()) { + return; + } + container = lpeitem->parent; + objindex = 0; + legacy = false; + bool creation = write; + SPShape *shape = getCurrentShape(); + SPCurve *curve = nullptr; + if (shape) { + curve = shape->curve(); + } + split(sp_lpe_item, curve, slicer, 0, creation); + bool connected = lpesatellites.is_connected(); + if (lpesatellites.data().size() && (creation || !connected)) { + lpesatellites.write_to_SVG(); + lpesatellites.start_listening(); + lpesatellites.update_satellites(!connected); + } + bool maindata = sp_has_path_data(sp_lpe_item, true); + for (auto & iter : lpesatellites.data()) { + SPObject *elemref; + if (iter && iter->isAttached() && (elemref = iter->getObject())) { + SPLPEItem *splpeitem = dynamic_cast(elemref); + if (splpeitem || lpeitem->isHidden()) { + if (!maindata || lpeitem->isHidden()) { + splpeitem->setHidden(true); + } + sp_lpe_item_update_patheffect(splpeitem, false, false); + } + } + } + if (!maindata) { + if (!curve) { // group + originalDtoD(sp_lpe_item); + } else { + originalDtoD(getCurrentShape(), curve); + } + return; + } + reset = false; + if (is_applied_on && prevslice) { + sp_lpe_item_update_patheffect(sp_lpe_item, false, false); + for (auto const &link : prevslice->lpesatellites.data()) { + if (link && link->isAttached()) { + SPGroup *spgrp = dynamic_cast(link->getObject()); + SPShape *spit = dynamic_cast(link->getObject()); + Glib::ustring transform = ""; + Glib::ustring patheffects = ""; + Geom::OptRect _gbbox = Geom::OptRect(); + if (spgrp) { + if (spgrp->getAttribute("transform")) { + transform = spgrp->getAttribute("transform"); + } + if (spgrp->getAttribute("inkscape:path-effect")) { + patheffects = spgrp->getAttribute("inkscape:path-effect"); + } + spgrp->setAttribute("transform", nullptr); + spgrp->setAttribute("inkscape:path-effect", nullptr); + _gbbox = spgrp->geometricBounds(); + } + if (spit || spgrp) { + for (auto const &link2 : lpesatellites.data()) { + if (link2 && link2->isAttached()) { + SPGroup *spgrp2 = dynamic_cast(link2->getObject()); + SPShape *spit2 = dynamic_cast(link2->getObject()); + if (spit && spit2) { + Geom::OptRect _bbox = spit->curveForEdit()->get_pathvector().boundsFast(); + Geom::OptRect _bbox2 = spit2->curveForEdit()->get_pathvector().boundsFast(); + if (_bbox && _bbox2) { + (*_bbox).expandBy(1); + if ((*_bbox).contains(*_bbox2)) { + spit2->setAttribute("transform", spit->getAttribute("transform")); + spit2->setAttribute("inkscape:path-effect", spit->getAttribute("inkscape:path-effect")); + spit2->setAttribute("style", spit->getAttribute("style")); + } + } + } else if (spgrp && spgrp2) { + Geom::OptRect _gbbox2 = spgrp2->geometricBounds(); + if (_gbbox && _gbbox2) { + (*_gbbox).expandBy(1); + if ((*_gbbox).contains(*_gbbox2)) { + spgrp2->setAttribute("transform", transform); + spgrp2->setAttribute("inkscape:path-effect", patheffects); + cloneStyle(spgrp, spgrp2); + } + } + } + } + } + if (spgrp) { + spgrp->setAttribute("transform", transform); + spgrp->setAttribute("inkscape:path-effect", patheffects); + } + } + } + } + + } + } else { + for (auto const &itemrf : lpesatellites.data()) { + if (itemrf && itemrf->isAttached()) { + SPLPEItem *splpeitem = dynamic_cast(itemrf->getObject()); + if (splpeitem) { + splpeitem->setHidden(true); + sp_lpe_item_update_patheffect(splpeitem, false, false); + } + } + } + } } void LPESlice::cloneStyle(SPObject *orig, SPObject *dest) @@ -932,6 +914,14 @@ LPESlice::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPESlice::doEffect_path (Geom::PathVector const & path_in) { + SPShape *shape = getCurrentShape(); + SPCurve *curve = nullptr; + if (shape) { + curve = shape->curve(); + } + if (curve) { + return curve->get_pathvector(); + } return path_in; } diff --git a/src/live_effects/lpe-slice.h b/src/live_effects/lpe-slice.h index 106a1abbf1..f7a3fd56c4 100644 --- a/src/live_effects/lpe-slice.h +++ b/src/live_effects/lpe-slice.h @@ -36,7 +36,6 @@ public: ~LPESlice() override; void doOnApply (SPLPEItem const* lpeitem) override; void doBeforeEffect (SPLPEItem const* lpeitem) override; - void doAfterEffect (SPLPEItem const* lpeitem, SPCurve *curve) override; Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; void doOnRemove (SPLPEItem const* /*lpeitem*/) override; void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) override; @@ -46,7 +45,7 @@ public: bool split(SPItem *item, SPCurve *curve, std::vector> slicer, size_t splitindex, bool &creation); bool splititem(SPItem *item, SPCurve *curve, std::pair slicer, bool toggle, - bool is_original = false); + bool is_original = false, Geom::Affine tpass = Geom::identity()); bool haschildslice(SPItem *item); std::vector > getSplitLines(); void cloneD(SPObject *orig, SPObject *dest, bool is_original); diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index b3685ac426..ca336f2549 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -68,9 +68,7 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : registerParameter(&lock_angle); first_knot.param_make_integer(); - first_knot.param_set_undo(false); last_knot.param_make_integer(); - last_knot.param_set_undo(false); helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); @@ -105,7 +103,11 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) point_b = pathvector.back().finalCurve().initialPoint(); } size_t nnodes = nodeCount(pathvector); + // this is need to fix undo on apply + first_knot.param_set_value(1); last_knot.param_set_value(nnodes); + first_knot.write_to_SVG(); + last_knot.write_to_SVG(); } previous_length = Geom::distance(point_a,point_b); @@ -208,8 +210,11 @@ LPETransform2Pts::updateIndex() end.param_update_default(point_b); start.param_set_default(); end.param_set_default(); + // seems silly but fix undo resetting value on it + first_knot.param_set_value(first_knot); + last_knot.param_set_value(last_knot); } - DocumentUndo::done(getSPDoc(), _("Change index of knot"), INKSCAPE_ICON("dialog-path-effects")); + refresh_widgets = true; } //todo migrate to PathVector class? size_t @@ -270,6 +275,7 @@ LPETransform2Pts::reset() first_knot.param_set_value(1); last_knot.param_set_value(2); } + refresh_widgets = true; offset.param_set_value(0.0); stretch.param_set_value(1.0); Geom::Ray transformed(point_a, point_b); diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index 96d655ab5b..2fb9279d34 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -83,9 +83,10 @@ BoolParam::param_newWidget() param_effect->getRepr(), param_effect->getSPDoc()) ); + // put here before the value set to get undo informed on first set value + checkwdg->set_undo_parameters(_("Change bool parameter"), INKSCAPE_ICON("dialog-path-effects")); checkwdg->setActive(value); checkwdg->setProgrammatically = false; - checkwdg->set_undo_parameters(_("Change bool parameter"), INKSCAPE_ICON("dialog-path-effects")); return dynamic_cast (checkwdg); } else { return nullptr; diff --git a/src/live_effects/parameter/colorpicker.cpp b/src/live_effects/parameter/colorpicker.cpp index cf9243e37f..074821af57 100644 --- a/src/live_effects/parameter/colorpicker.cpp +++ b/src/live_effects/parameter/colorpicker.cpp @@ -120,12 +120,13 @@ ColorPickerParam::param_newWidget() *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ); + // put here before the value set to get undo informed on first set value + colorpickerwdg->set_undo_parameters(_("Change color button parameter"), INKSCAPE_ICON("dialog-path-effects")); SPDocument *document = param_effect->getSPDoc(); bool saved = DocumentUndo::getUndoSensitive(document); DocumentUndo::setUndoSensitive(document, false); colorpickerwdg->setRgba32(value); DocumentUndo::setUndoSensitive(document, saved); - colorpickerwdg->set_undo_parameters(_("Change color button parameter"), INKSCAPE_ICON("dialog-path-effects")); hbox->pack_start(*dynamic_cast (colorpickerwdg), true, true); return dynamic_cast (hbox); } diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp index 441f14e6c5..9846a836a1 100644 --- a/src/live_effects/parameter/fontbutton.cpp +++ b/src/live_effects/parameter/fontbutton.cpp @@ -77,8 +77,9 @@ FontButtonParam::param_newWidget() param_effect->getRepr(), param_effect->getSPDoc() ) ); Glib::ustring fontspec = param_getSVGValue(); - fontbuttonwdg->setValue( fontspec); + // put here before the value set to get undo informed on first set value fontbuttonwdg->set_undo_parameters(_("Change font button parameter"), INKSCAPE_ICON("dialog-path-effects")); + fontbuttonwdg->setValue(fontspec); return dynamic_cast (fontbuttonwdg); } diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index d58804b7e0..3b6ec3c58a 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -304,6 +304,10 @@ void ScalarParam::param_transform_multiply(Geom::Affine const &postmul, bool set void ScalarParam::param_set_value(gdouble val) { + // we need to refesh widgets on change value to properly display value + if (value != val) { + param_effect->refresh_widgets = true; + } value = val; if (integer) value = round(value); @@ -349,6 +353,9 @@ Gtk::Widget *ScalarParam::param_newWidget() Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage(new Inkscape::UI::Widget::RegisteredScalar( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc())); + if (_set_undo) { + rsu->set_undo_parameters(_("Change scalar parameter"), INKSCAPE_ICON("dialog-path-effects")); + } rsu->setValue(value); rsu->setDigits(digits); rsu->setIncrements(inc_step, inc_page); @@ -357,9 +364,6 @@ Gtk::Widget *ScalarParam::param_newWidget() if (add_slider) { rsu->addSlider(); } - if (_set_undo) { - rsu->set_undo_parameters(_("Change scalar parameter"), INKSCAPE_ICON("dialog-path-effects")); - } return dynamic_cast(rsu); } else { return nullptr; diff --git a/src/live_effects/parameter/patharray.cpp b/src/live_effects/parameter/patharray.cpp index 11d4c39cda..8204239a8d 100644 --- a/src/live_effects/parameter/patharray.cpp +++ b/src/live_effects/parameter/patharray.cpp @@ -141,7 +141,7 @@ void PathArrayParam::on_reverse_toggled(const Glib::ustring &path) w->reversed = row[_model->_colReverse]; param_write_to_repr(param_getSVGValue().c_str()); - DocumentUndo::done(param_effect->getSPDoc(), _("Link path parameter to path"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Link path parameter to path"),INKSCAPE_ICON("dialog-path-effects")); } void PathArrayParam::on_visible_toggled(const Glib::ustring &path) @@ -153,7 +153,7 @@ void PathArrayParam::on_visible_toggled(const Glib::ustring &path) w->visibled = row[_model->_colVisible]; param_write_to_repr(param_getSVGValue().c_str()); - DocumentUndo::done(param_effect->getSPDoc(), _("Toggle path parameter visibility"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Toggle path parameter visibility"),INKSCAPE_ICON("dialog-path-effects")); } void PathArrayParam::param_set_default() {} @@ -265,8 +265,7 @@ void PathArrayParam::on_up_button_click() } param_write_to_repr(param_getSVGValue().c_str()); - - DocumentUndo::done(param_effect->getSPDoc(), _("Move path up"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Move path up"),INKSCAPE_ICON("dialog-path-effects")); _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &PathArrayParam::_selectIndex), &i)); } @@ -292,8 +291,7 @@ void PathArrayParam::on_down_button_click() } param_write_to_repr(param_getSVGValue().c_str()); - - DocumentUndo::done(param_effect->getSPDoc(), _("Move path down"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Move path down"),INKSCAPE_ICON("dialog-path-effects")); _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &PathArrayParam::_selectIndex), &i)); } @@ -307,8 +305,7 @@ void PathArrayParam::on_remove_button_click() unlink(row[_model->_colObject]); param_write_to_repr(param_getSVGValue().c_str()); - - DocumentUndo::done(param_effect->getSPDoc(), _("Remove path"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Remove path"),INKSCAPE_ICON("dialog-path-effects")); } } @@ -343,7 +340,7 @@ void PathArrayParam::on_link_button_click() os << pathid.c_str() << ",0,1"; } param_write_to_repr(os.str().c_str()); - DocumentUndo::done(param_effect->getSPDoc(), _("Link patharray parameter to path"), INKSCAPE_ICON("dialog-path-effects")); + DocumentUndo::done(param_effect->getSPDoc(),_("Link patharray parameter to path"),INKSCAPE_ICON("dialog-path-effects")); } void PathArrayParam::unlink(PathAndDirectionAndVisible *to) diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index f99a0980b5..5285e3a0be 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -157,10 +157,11 @@ PointParam::param_newWidget() param_effect->getRepr(), param_effect->getSPDoc() ) ); Geom::Affine transf = SP_ACTIVE_DESKTOP->doc2dt(); + // put here before the value set to get undo informed on first set value + pointwdg->set_undo_parameters(_("Change point parameter"), INKSCAPE_ICON("dialog-path-effects")); pointwdg->setTransform(transf); pointwdg->setValue( *this ); pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(_("Change point parameter"), INKSCAPE_ICON("dialog-path-effects")); pointwdg->signal_button_release_event().connect(sigc::mem_fun (*this, &PointParam::on_button_release)); Gtk::Box * hbox = Gtk::manage( new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) ); diff --git a/src/live_effects/parameter/satellite.cpp b/src/live_effects/parameter/satellite.cpp index 989a73a774..b06cf148f7 100644 --- a/src/live_effects/parameter/satellite.cpp +++ b/src/live_effects/parameter/satellite.cpp @@ -163,7 +163,7 @@ void SatelliteParam::link(Glib::ustring itemid) } else { param_write_to_repr(""); } - DocumentUndo::done(document, _("Link item parameter to path"), ""); + DocumentUndo::done(param_effect->getSPDoc(), _("Link item parameter to path"), INKSCAPE_ICON("dialog-path-effects")); } // SIGNALS diff --git a/src/live_effects/parameter/satellitearray.cpp b/src/live_effects/parameter/satellitearray.cpp index 559aed1d15..27425dfdae 100644 --- a/src/live_effects/parameter/satellitearray.cpp +++ b/src/live_effects/parameter/satellitearray.cpp @@ -11,6 +11,7 @@ #include "inkscape.h" #include "ui/clipboard.h" #include "ui/icon-loader.h" +#include "ui/icon-names.h" #include namespace Inkscape { @@ -159,7 +160,7 @@ void SatelliteArrayParam::on_active_toggled(const Glib::ustring &item) } auto full = param_getSVGValue(); param_write_to_repr(full.c_str()); - DocumentUndo::done(param_effect->getSPDoc(), _("Active switched"), ""); + DocumentUndo::done(param_effect->getSPDoc(), _("Active switched"), INKSCAPE_ICON("dialog-path-effects")); } bool SatelliteArrayParam::param_readSVGValue(const gchar *strvalue) @@ -240,8 +241,7 @@ void SatelliteArrayParam::on_up_button_click() auto full = param_getSVGValue(); param_write_to_repr(full.c_str()); - DocumentUndo::done(param_effect->getSPDoc(), _("Move item up"), ""); - + DocumentUndo::done(param_effect->getSPDoc(), _("Move item up"), INKSCAPE_ICON("dialog-path-effects")); _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &SatelliteArrayParam::_selectIndex), &i)); } } @@ -265,8 +265,7 @@ void SatelliteArrayParam::on_down_button_click() } auto full = param_getSVGValue(); param_write_to_repr(full.c_str()); - - DocumentUndo::done(param_effect->getSPDoc(), _("Move item down"), ""); + DocumentUndo::done(param_effect->getSPDoc(), _("Move item down"), INKSCAPE_ICON("dialog-path-effects")); _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &SatelliteArrayParam::_selectIndex), &i)); } @@ -281,8 +280,7 @@ void SatelliteArrayParam::on_remove_button_click() auto full = param_getSVGValue(); param_write_to_repr(full.c_str()); - - DocumentUndo::done(param_effect->getSPDoc(), _("Remove item"), ""); + DocumentUndo::done(param_effect->getSPDoc(), _("Remove item"), INKSCAPE_ICON("dialog-path-effects")); } } @@ -330,7 +328,7 @@ void SatelliteArrayParam::on_link_button_click() } } write_to_SVG(); - DocumentUndo::done(param_effect->getSPDoc(), _("Link itemarray parameter to item"), ""); + DocumentUndo::done(param_effect->getSPDoc(), _("Link itemarray parameter to item"), INKSCAPE_ICON("dialog-path-effects")); } Gtk::Widget *SatelliteArrayParam::param_newWidget() diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index ea0171dc2e..d8c99b6d99 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -142,9 +142,10 @@ TextParam::param_newWidget() { Inkscape::UI::Widget::RegisteredText *rsu = Gtk::manage(new Inkscape::UI::Widget::RegisteredText( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc())); + // put here before the value set to get undo informed on first set value + rsu->set_undo_parameters(_("Change text parameter"), INKSCAPE_ICON("dialog-path-effects")); rsu->setText(value); rsu->setProgrammatically = false; - rsu->set_undo_parameters(_("Change text parameter"), INKSCAPE_ICON("dialog-path-effects")); Gtk::Box *text_container = Gtk::manage(new Gtk::Box()); Gtk::Button *set = Gtk::manage(new Gtk::Button(Glib::ustring("✔"))); set->signal_clicked() diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index 9b2b41ffb4..4838ef846c 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -115,10 +115,11 @@ TransformedPointParam::param_newWidget() *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + // put here before the value set to get undo informed on first set value + pointwdg->set_undo_parameters(_("Change vector parameter"), INKSCAPE_ICON("dialog-path-effects")); pointwdg->setPolarCoords(); pointwdg->setValue( vector, origin ); pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(_("Change vector parameter"), INKSCAPE_ICON("dialog-path-effects")); Gtk::Box * hbox = Gtk::manage( new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) ); hbox->pack_start(*pointwdg, true, true); diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp index 16b83fb791..204b2119bc 100644 --- a/src/live_effects/parameter/vector.cpp +++ b/src/live_effects/parameter/vector.cpp @@ -112,10 +112,11 @@ VectorParam::param_newWidget() *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + // put here before the value set to get undo informed on first set value + pointwdg->set_undo_parameters(_("Change vector parameter"), INKSCAPE_ICON("dialog-path-effects")); pointwdg->setPolarCoords(); pointwdg->setValue( vector, origin ); pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(_("Change vector parameter"), INKSCAPE_ICON("dialog-path-effects")); Gtk::Box * hbox = Gtk::manage( new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) ); hbox->pack_start(*pointwdg, true, true); diff --git a/src/object/box3d-side.cpp b/src/object/box3d-side.cpp index d48f6aa66d..7aed9abc35 100644 --- a/src/object/box3d-side.cpp +++ b/src/object/box3d-side.cpp @@ -205,7 +205,6 @@ void Box3DSide::set_shape() { return; } - // This happends on undo, fix bug:#1791784 setCurveInsync(std::move(c)); } diff --git a/src/object/sp-ellipse.cpp b/src/object/sp-ellipse.cpp index 8f471d14a2..83b39f37b1 100644 --- a/src/object/sp-ellipse.cpp +++ b/src/object/sp-ellipse.cpp @@ -491,11 +491,7 @@ void SPGenericEllipse::set_shape() // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); c.transform(aff); - if (prepareShapeForLPE(&c)) { - return; - } - // This happends on undo, fix bug:#1791784 - setCurveInsync(std::move(c)); + prepareShapeForLPE(&c); } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 2994db4862..68802f3680 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -306,11 +306,6 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: } lpe->doAfterEffect_impl(this, curve); } - // we need this on slice LPE to calculate effects correctly - if (dynamic_cast(lpe)) { // we are on 1 or up - current->bbox_vis_cache_is_valid = false; - current->bbox_geom_cache_is_valid = false; - } } } return true; diff --git a/src/object/sp-rect.cpp b/src/object/sp-rect.cpp index 80dee3fe51..89e143e1d6 100644 --- a/src/object/sp-rect.cpp +++ b/src/object/sp-rect.cpp @@ -279,12 +279,7 @@ void SPRect::set_shape() { c.closepath(); - if (prepareShapeForLPE(&c)) { - return; - } - - // This happends on undo, fix bug:#1791784 - setCurveInsync(std::move(c)); + prepareShapeForLPE(&c); } bool SPRect::set_rect_path_attribute(Inkscape::XML::Node *repr) diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index af4c6e1911..8b71fb135c 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -485,13 +485,13 @@ bool SPShape::checkBrokenPathEffect() /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ -bool SPShape::prepareShapeForLPE(SPCurve const *c) +void SPShape::prepareShapeForLPE(SPCurve const *c) { auto const before = curveBeforeLPE(); if (before && before->get_pathvector() != c->get_pathvector()) { setCurveBeforeLPE(c); sp_lpe_item_update_patheffect(this, true, false); - return true; + return; } if (hasPathEffectOnClipOrMaskRecursive(this)) { @@ -499,9 +499,9 @@ bool SPShape::prepareShapeForLPE(SPCurve const *c) setCurveInsync(SPCurve(sp_svg_read_pathv(getAttribute("d")))); } setCurveBeforeLPE(c); - return true; + return; } - return false; + setCurveInsync(c); } Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const { diff --git a/src/object/sp-shape.h b/src/object/sp-shape.h index cb40e01a15..f5ddff94e7 100644 --- a/src/object/sp-shape.h +++ b/src/object/sp-shape.h @@ -53,7 +53,7 @@ public: void setCurveBeforeLPE(SPCurve const *); void setCurveBeforeLPE(SPCurve); bool checkBrokenPathEffect(); - bool prepareShapeForLPE(SPCurve const *c); + void prepareShapeForLPE(SPCurve const *c); int hasMarkers () const; int numberOfMarkers (int type) const; diff --git a/src/object/sp-spiral.cpp b/src/object/sp-spiral.cpp index d6284f2ad3..f653340483 100644 --- a/src/object/sp-spiral.cpp +++ b/src/object/sp-spiral.cpp @@ -336,12 +336,8 @@ void SPSpiral::set_shape() { this->fitAndDraw(&c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); } - if (prepareShapeForLPE(&c)) { - return; - } + prepareShapeForLPE(&c); - // This happends on undo, fix bug:#1791784 - setCurveInsync(std::move(c)); } /** diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 8365037da4..8b4c04ab72 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -419,12 +419,8 @@ void SPStar::set_shape() { c.closepath(); - if (prepareShapeForLPE(&c)) { - return; - } + prepareShapeForLPE(&c); - // This happends on undo, fix bug:#1791784 - setCurveInsync(std::move(c)); } void diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index 0e617a3b1b..71c014df7e 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -218,15 +218,6 @@ UndoHistory::_onListSelectionChange() /* If no event is selected in the view, find the right one and select it. This happens whenever * a branch we're currently in is collapsed. */ - // this fix crashes on redo with knots forcing regenerate knots on undo - SPDesktop *dt = getDesktop(); - Glib::ustring switch_selector_to = ""; - if (dt) { - switch_selector_to = get_active_tool(dt); - if (switch_selector_to != "Select") { - set_active_tool(dt, "Select"); - } - } if (!selected) { EventLog::iterator curr_event = _event_log->getCurrEvent(); @@ -271,7 +262,7 @@ UndoHistory::_onListSelectionChange() _event_log->blockNotifications(); while ( selected != last_selected ) { - + getDocument()->ensureUpToDate(); DocumentUndo::undo(getDocument()); if ( last_selected->parent() && @@ -292,11 +283,11 @@ UndoHistory::_onListSelectionChange() _event_log->updateUndoVerbs(); } else { // An event after the current one has been selected. Redo to the selected event. - + EventLog::const_iterator last_selected = _event_log->getCurrEvent(); _event_log->blockNotifications(); while ( selected != last_selected ) { - + getDocument()->ensureUpToDate(); DocumentUndo::redo(getDocument()); if ( !last_selected->children().empty() ) { @@ -320,9 +311,6 @@ UndoHistory::_onListSelectionChange() _event_log->setCurrEvent(selected); _event_log->updateUndoVerbs(); } - if (dt && switch_selector_to != "Select") { - set_active_tool(dt, switch_selector_to); - } } void @@ -338,15 +326,6 @@ UndoHistory::_onCollapseEvent(const Gtk::TreeModel::iterator &iter, const Gtk::T { // Collapsing a branch we're currently in is equal to stepping to the last event in that branch if ( iter == _event_log->getCurrEvent() ) { - // this fix crashes on redo with knots forcing regenerate knots on undo - SPDesktop *dt = getDesktop(); - Glib::ustring switch_selector_to = ""; - if (dt) { - switch_selector_to = get_active_tool(dt); - if (switch_selector_to != "Select") { - set_active_tool(dt, "Select"); - } - } EventLog::const_iterator curr_event_parent = _event_log->getCurrEvent(); EventLog::const_iterator curr_event = curr_event_parent->children().begin(); EventLog::const_iterator last = curr_event_parent->children().end(); @@ -362,9 +341,6 @@ UndoHistory::_onCollapseEvent(const Gtk::TreeModel::iterator &iter, const Gtk::T _event_log->setCurrEvent(curr_event); _event_log->setCurrEventParent(curr_event_parent); _event_list_selection->select(curr_event_parent); - if (dt && switch_selector_to != "Select") { - set_active_tool(dt, switch_selector_to); - } } } diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index f843540779..6e7e895833 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -115,20 +115,14 @@ protected: local_doc = dt->getDocument(); } - bool saved = DocumentUndo::getUndoSensitive(local_doc); - DocumentUndo::setUndoSensitive(local_doc, false); const char * svgstr_old = local_repr->attribute(_key.c_str()); - if (!write_undo) { - local_repr->setAttribute(_key, svgstr); - } - DocumentUndo::setUndoSensitive(local_doc, saved); - if (svgstr_old && svgstr && strcmp(svgstr_old,svgstr)) { + // do nothing when no changes + if (g_strcmp0(svgstr_old, svgstr)) { local_doc->setModifiedSinceSave(); - } - - if (write_undo) { local_repr->setAttribute(_key, svgstr); - DocumentUndo::done(local_doc, event_description, icon_name); + if (write_undo) { + DocumentUndo::done(local_doc, event_description, icon_name); + } } } @@ -138,7 +132,7 @@ protected: SPDocument * doc = nullptr; Glib::ustring event_description; Glib::ustring icon_name; // Used by History dialog. - bool write_undo = false; + bool write_undo = false; // only used by LPE }; //####################################################### -- GitLab