diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index ad4f8f9e91c1572954e1d9a36a389e61ef14dbf5..c35dfedf492a0a287648a4ea13938ad8564a0cb1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -1204,12 +1204,6 @@ Effect::doOnApply (SPLPEItem const*/*lpeitem*/) { } -void -Effect::setCurrentZoom(double cZ) -{ - current_zoom = cZ; -} - /** * Overridden function to apply transforms for example to powerstroke, jointtype or tapperstroke */ @@ -1542,6 +1536,11 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); + if (SP_ACTIVE_DESKTOP) { + //we need to set here instead in helper patths because clips/mask itens with LPE are not is selection + current_zoom = SP_ACTIVE_DESKTOP->current_zoom(); + } + doBeforeEffect(lpeitem); if (is_load) { update_satellites(); diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 8ceecfba70368104cf9b89e55d67ea43fd67596b..c7e2f3f7d5365845d9d375e8c8d41bb020de5738 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -77,7 +77,6 @@ public: void transform_multiply_impl(Geom::Affine const &postmul, SPLPEItem *); void doOnBeforeCommit(); void read_from_SVG(); - void setCurrentZoom(double cZ); void setSelectedNodePoints(std::vector sNP); bool isNodePointSelected(Geom::Point const &nodePoint) const; bool isOnClipboard(); @@ -152,6 +151,7 @@ public: void setLPEAction(LPEAction lpe_action) { _lpe_action = lpe_action; } BoolParam is_visible; HiddenParam lpeversion; + double current_zoom = 1; Geom::PathVector pathvector_before_effect; Geom::PathVector pathvector_after_effect; SPLPEItem *sp_lpe_item = nullptr; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with @@ -191,7 +191,6 @@ protected: // this boolean defaults to false, it concatenates the input path to one pwd2, // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; - double current_zoom; std::vector selectedNodesPoints; Inkscape::UI::Widget::Registry wr; private: diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 60b7f0e3ea172619623f10230249509cd416f8a6..9c8b29020e00495f4a5f21a4b4fd36c4ffa5b964 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -303,7 +303,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) if (!pathvector_before_effect.empty()) { //fillet chamfer specific calls nodesatellites_param.setUseDistance(use_knot_distance); - nodesatellites_param.setCurrentZoom(current_zoom); //mandatory call nodesatellites_param.setEffectType(effectType()); Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(pathvector_before_effect); diff --git a/src/live_effects/lpe-powerclip.cpp b/src/live_effects/lpe-powerclip.cpp index e6f3227c1892475ace61509bd944b67b40a63c70..b7017112330e88cbd46c8ba74cc1cf7d10d84163 100644 --- a/src/live_effects/lpe-powerclip.cpp +++ b/src/live_effects/lpe-powerclip.cpp @@ -110,6 +110,9 @@ Geom::PathVector LPEPowerClip::getClipPathvector() for (auto clip : clip_path_list) { auto childitem = cast(clip); if (childitem) { + if (!_updating) { + sp_lpe_item_update_patheffect(childitem, false, true); + } res_hlp = sp_get_recursive_pathvector(childitem, res_hlp, false, inverse); if (is_load && _legacy) { childitem->doWriteTransform(Geom::Translate(0, -999999)); @@ -150,6 +153,9 @@ void LPEPowerClip::add() SPObject *clip_path = sp_lpe_item->getClipObject(); SPObject *elemref = NULL; if (clip_path) { + modified_connection = clip_path->connectModified([this] (auto a, unsigned flags) { + modified(a, flags); + }); Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *parent = clip_path->getRepr(); auto childitems = clip_path->childList(true); @@ -211,15 +217,32 @@ void LPEPowerClip::upd() } +void +LPEPowerClip::modified(auto, unsigned flags) { + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG) && !_updating) { + _updating = true; + upd(); + _updating = false; + } +} + void LPEPowerClip::doBeforeEffect(SPLPEItem const *lpeitem) { if (!_updating) { upd(); } + if (is_load) { + SPObject *clip_path = sp_lpe_item->getClipObject(); + if (clip_path) { + modified_connection = clip_path->connectModified([this] (auto a, unsigned flags) { + modified(a, flags); + }); + } + } } void -LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) +LPEPowerClip::doOnRemove (SPLPEItem const* lpeitem) { SPDocument *document = getSPDoc(); if (!document) { @@ -234,12 +257,17 @@ LPEPowerClip::doOnRemove (SPLPEItem const* /*lpeitem*/) } return; } + SPObject *clip_path = lpeitem->getClipObject(); + if (clip_path) { + inverse.param_setValue(false); + upd(); + } + _updating = true; SPObject *elemref = document->getObjectById(getId().c_str()); if (elemref) { elemref->deleteObject(); } - SPObject *clip_path = sp_lpe_item->getClipObject(); if (clip_path) { std::vector clip_path_list = clip_path->childList(true); for (auto clip : clip_path_list) { diff --git a/src/live_effects/lpe-powerclip.h b/src/live_effects/lpe-powerclip.h index fa857884d5c320bc11460414f25c802b3e06d6e3..09500277f3071f0488222084edba7f1124a213de 100644 --- a/src/live_effects/lpe-powerclip.h +++ b/src/live_effects/lpe-powerclip.h @@ -10,6 +10,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/message.h" +#include "helper/auto-connection.h" namespace Inkscape { namespace LivePathEffect { @@ -22,6 +23,7 @@ public: Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; void doOnRemove(SPLPEItem const* /*lpeitem*/) override; void doOnVisibilityToggled(SPLPEItem const* lpeitem) override; + void modified(auto, unsigned flags); Glib::ustring getId(); void add(); void upd(); @@ -33,6 +35,7 @@ public: BoolParam flatten; BoolParam hide_clip; MessageParam message; + auto_connection modified_connection; bool _updating; bool _legacy; }; diff --git a/src/live_effects/lpe-powermask.cpp b/src/live_effects/lpe-powermask.cpp index 63e748abeb3c8bc0c53fc9830329abcb26d45d6a..eba66d904cd535f0c32c029987b17a3bb81c9d33 100644 --- a/src/live_effects/lpe-powermask.cpp +++ b/src/live_effects/lpe-powermask.cpp @@ -207,7 +207,7 @@ LPEPowerMask::setMask(){ for (auto iter : mask_list) { auto mask_data = cast(iter); Inkscape::XML::Node *mask_node = mask_data->getRepr(); - if (! strcmp(mask_data->getId(), box_id.c_str())){ + if (!strcmp(mask_data->getId(), box_id.c_str())) { continue; } Glib::ustring mask_data_id = (Glib::ustring)mask_data->getId(); @@ -226,6 +226,10 @@ LPEPowerMask::setMask(){ sp_repr_css_write_string(css, css_str); mask_node->setAttribute("style", css_str); } + auto *maskitem = cast(iter); + if (maskitem && maskitem->hasPathEffect()) { + sp_lpe_item_update_patheffect(maskitem, false, false); + } } if ((elemref = document->getObjectById(box_id))) { elemref->deleteObject(true); diff --git a/src/live_effects/parameter/nodesatellitesarray.cpp b/src/live_effects/parameter/nodesatellitesarray.cpp index 38b142bc68120edb29a54227a01a4588469adae3..feb9232e75bc29ce42855c92d4d0501a3d7a13a3 100644 --- a/src/live_effects/parameter/nodesatellitesarray.cpp +++ b/src/live_effects/parameter/nodesatellitesarray.cpp @@ -83,11 +83,6 @@ void NodeSatelliteArrayParam::setUseDistance(bool use_knot_distance) _use_distance = use_knot_distance; } -void NodeSatelliteArrayParam::setCurrentZoom(double current_zoom) -{ - _current_zoom = current_zoom; -} - void NodeSatelliteArrayParam::setGlobalKnotHide(bool global_knot_hide) { _global_knot_hide = global_knot_hide; @@ -310,10 +305,7 @@ void FilletChamferKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point normal = pathv[satelite_index][subsatelite_index].pointAt(normal_time); double distance_mirror = Geom::distance(mirror,s); double distance_normal = Geom::distance(normal,s); - if ((normal_time == 0 && !is_mirror) || - (mirror_time == 1 && is_mirror) || - Geom::are_near(s, pathv[satelite_index][subsatelite_index].initialPoint(), 1.5 / _pparam->_current_zoom)) - { + if (Geom::are_near(s, pathv[satelite_index][subsatelite_index].initialPoint(), 1.5 / _pparam->param_effect->current_zoom)) { nodesatellite.amount = 0; } else if (distance_mirror < distance_normal) { double time_start = 0; @@ -481,9 +473,9 @@ Geom::Point FilletChamferKnotHolderEntity::knot_get() const } } - if (_pparam->_current_zoom && - (Geom::are_near(ssat_path.pointAt(0), ssat_path.pointAt(0.1), 0.5 / _pparam->_current_zoom) || - Geom::are_near(prev_path.pointAt(0), prev_path.pointAt(0.1), 0.5 / _pparam->_current_zoom))) + if (_pparam->param_effect->current_zoom && + (Geom::are_near(ssat_path.pointAt(0), ssat_path.pointAt(0.1), 0.5 / _pparam->param_effect->current_zoom) || + Geom::are_near(prev_path.pointAt(0), prev_path.pointAt(0.1), 0.5 / _pparam->param_effect->current_zoom))) { knot->hide(); } diff --git a/src/live_effects/parameter/nodesatellitesarray.h b/src/live_effects/parameter/nodesatellitesarray.h index 49855db2286a0f5cac61c87e761e13a61a8b7afe..ce95ec23de6728e782e9274ea0e63f6355b745bc 100644 --- a/src/live_effects/parameter/nodesatellitesarray.h +++ b/src/live_effects/parameter/nodesatellitesarray.h @@ -54,7 +54,6 @@ public: } void param_transform_multiply(Geom::Affine const &postmul, bool /*set*/) override; void setUseDistance(bool use_knot_distance); - void setCurrentZoom(double current_zoom); void setGlobalKnotHide(bool global_knot_hide); void setEffectType(EffectType et); void reloadKnots(); @@ -76,7 +75,6 @@ private: Geom::PathVector _hp; bool _use_distance = false; bool _global_knot_hide = false; - double _current_zoom = 0; EffectType _effectType = FILLET_CHAMFER; PathVectorNodeSatellites *_last_pathvector_nodesatellites = nullptr; }; diff --git a/src/object/sp-mask.cpp b/src/object/sp-mask.cpp index b0f7fd94a5e9cc91a0bee9a840fc87605e08f549..32e148c62d49a678d83d54eb8e4a5249b2a23f76 100644 --- a/src/object/sp-mask.cpp +++ b/src/object/sp-mask.cpp @@ -23,6 +23,7 @@ #include "document.h" // for SPDocument #include "enums.h" // for SP_CONTENT_UNITS... #include "sp-defs.h" // for SPDefs +#include "sp-lpe-item.h" // for LPEItems #include "sp-item.h" // for SPItem, SP_ITEM_... #include "xml/document.h" // for Document @@ -204,6 +205,10 @@ char const *SPMask::create(std::vector &reprs, SPDocument for (auto node : reprs) { mask_object->appendChildRepr(node); + SPLPEItem *maskitem = cast(document->getObjectByRepr(node)); + if (maskitem && maskitem->hasPathEffect()) { + sp_lpe_item_update_patheffect(maskitem, false, false); + } } if (repr != defsrepr->lastChild()) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f572883bc7a46e7e7220d6b8d5bdfa94615f7a29..aed0e4b6c09c05aed966ccc0958bee5c34c010c8 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3988,6 +3988,15 @@ void ObjectSet::setClipGroup() for (auto i : items_to_delete) { SPObject *item = reinterpret_cast(i); + auto lpeitem = cast(item); + if (lpeitem) { + // we need to do because deleting item and resurrect on clipboard + // cause delete all refs and this are not regenerated because on cliboard + // stude increase SPObject delete function to not remove LPE + // if we notice more similar pattern + // See to improve: https://gitlab.com/inkscape/inkscape/-/merge_requests/4843#note_1425238668 + lpeitem->setAttribute("inkscape:path-effect", nullptr); + } item->deleteObject(false); items_to_select.erase(std::remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end()); } diff --git a/src/ui/knot/knot-holder-entity.cpp b/src/ui/knot/knot-holder-entity.cpp index 3ec4bc5257a87e11db78a3f6a8682adfd5661419..d405dcedb7e92fbe04268140f3d6f2e816b1d09d 100644 --- a/src/ui/knot/knot-holder-entity.cpp +++ b/src/ui/knot/knot-holder-entity.cpp @@ -74,7 +74,7 @@ KnotHolderEntity::~KnotHolderEntity() void KnotHolderEntity::update_knot() { - if (auto const knot_pos = knot_get(); knot_pos.isFinite()) { + if (auto const knot_pos = knot_get(); knot_pos.isFinite() && item->document) { auto const dp = knot_pos * parent_holder->getEditTransform() * item->i2dt_affine(); _moved_connection.block(); knot->setPosition(dp, SP_KNOT_STATE_NORMAL); diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index adb6f56a7a9969fb503832d9fbcd52ef7ff0bf10..64da9c20d11c8b76b884a51275f9eb10ed74d459 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -258,7 +258,6 @@ void sp_update_helperpath(SPDesktop *desktop) } } lpe->setSelectedNodePoints(selectedNodesPositions); - lpe->setCurrentZoom(desktop->current_zoom()); SPCurve c; std::vector cs = lpe->getCanvasIndicators(lpeitem); for (auto &p : cs) {