From f4b9ad09e3041e0f0e0d99666b7c514f85b9a93f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Thu, 21 Jan 2021 00:37:05 +0100 Subject: [PATCH] This MR fix a issue when closing document. LPE items are destooyed calling to remove path effects but in this time sp_lpe_item is not available and inkscape crash when we delete a LPE item with affected effects To solve it I use a Thomas fix for transforming LPE and use hreflist to refresh the sp_lpe_item if ref is valid --- src/live_effects/lpe-bool.cpp | 26 +++++++++----- src/live_effects/lpe-copy_rotate.cpp | 21 ++++++++---- src/live_effects/lpe-measure-segments.cpp | 21 ++++++++---- src/live_effects/lpe-mirror_symmetry.cpp | 18 +++++++--- src/live_effects/lpe-slice.cpp | 42 ++++++++++++++--------- 5 files changed, 85 insertions(+), 43 deletions(-) diff --git a/src/live_effects/lpe-bool.cpp b/src/live_effects/lpe-bool.cpp index 09b0ccf02d..13291620ce 100644 --- a/src/live_effects/lpe-bool.cpp +++ b/src/live_effects/lpe-bool.cpp @@ -667,15 +667,23 @@ void LPEBool::addCanvasIndicators(SPLPEItem const * /*lpeitem*/, std::vector(operand_path.getObject()); - if (operand) { - if (keep_paths) { - if (is_visible) { - operand->deleteObject(true); - } - } else { - if (is_visible) { - remove_filter(); + // use hreflist method to update sp_lpe_item because can be bad referenced + items.clear(); + auto hreflist = getLPEObj()->hrefList; + if (hreflist.size()) { + sp_lpe_item = dynamic_cast(hreflist.back()); + if (sp_lpe_item) { + SPItem *operand = dynamic_cast(operand_path.getObject()); + if (operand) { + if (keep_paths) { + if (is_visible) { + operand->deleteObject(true); + } + } else { + if (is_visible) { + remove_filter(); + } + } } } } diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 5675f4438c..fab908c9c9 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -667,13 +667,22 @@ LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPECopyRotate::doOnRemove (SPLPEItem const* lpeitem) { - //set "keep paths" hook on sp-lpe-item.cpp - if (keep_paths) { - processObjects(LPE_TO_OBJECTS); - items.clear(); - return; + // set "keep paths" hook on sp-lpe-item.cpp + // use hreflist method to update sp_lpe_item because can be bad referenced + items.clear(); + auto hreflist = getLPEObj()->hrefList; + if (hreflist.size()) { + sp_lpe_item = dynamic_cast(hreflist.back()); + if (sp_lpe_item) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { + processObjects(LPE_TO_OBJECTS); + items.clear(); + return; + } + processObjects(LPE_ERASE); + } } - processObjects(LPE_ERASE); } } //namespace LivePathEffect diff --git a/src/live_effects/lpe-measure-segments.cpp b/src/live_effects/lpe-measure-segments.cpp index 42293aad90..765ab777ef 100644 --- a/src/live_effects/lpe-measure-segments.cpp +++ b/src/live_effects/lpe-measure-segments.cpp @@ -1207,13 +1207,22 @@ LPEMeasureSegments::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) void LPEMeasureSegments::doOnRemove (SPLPEItem const* /*lpeitem*/) { - //set "keep paths" hook on sp-lpe-item.cpp - if (keep_paths) { - processObjects(LPE_TO_OBJECTS); - items.clear(); - return; + // set "keep paths" hook on sp-lpe-item.cpp + // use hreflist method to update sp_lpe_item because can be bad referenced + items.clear(); + auto hreflist = getLPEObj()->hrefList; + if (hreflist.size()) { + sp_lpe_item = dynamic_cast(hreflist.back()); + if (sp_lpe_item) { + //set "keep paths" hook on sp-lpe-item.cpp + if (keep_paths) { + processObjects(LPE_TO_OBJECTS); + items.clear(); + return; + } + processObjects(LPE_ERASE); + } } - processObjects(LPE_ERASE); } }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index e7510a355d..c696766fb9 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -413,12 +413,20 @@ void LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) { //set "keep paths" hook on sp-lpe-item.cpp - if (keep_paths) { - processObjects(LPE_TO_OBJECTS); - items.clear(); - return; + // use hreflist method to update sp_lpe_item because can be bad referenced + items.clear(); + auto hreflist = getLPEObj()->hrefList; + if (hreflist.size()) { + sp_lpe_item = dynamic_cast(hreflist.back()); + if (sp_lpe_item) { + if (keep_paths) { + processObjects(LPE_TO_OBJECTS); + items.clear(); + return; + } + processObjects(LPE_ERASE); + } } - processObjects(LPE_ERASE); } void diff --git a/src/live_effects/lpe-slice.cpp b/src/live_effects/lpe-slice.cpp index d941e1d853..f6c5db00b4 100644 --- a/src/live_effects/lpe-slice.cpp +++ b/src/live_effects/lpe-slice.cpp @@ -701,24 +701,32 @@ void LPESlice::doOnRemove (SPLPEItem const* /*lpeitem*/) { //set "keep paths" hook on sp-lpe-item.cpp + // use hreflist method to update sp_lpe_item because can be bad referenced items.clear(); - Glib::ustring theclass = sp_lpe_item->getId(); - theclass += "-slice"; - for (auto item : getSPDoc()->getObjectsByClass(theclass)) { - items.emplace_back(item->getId()); - } - if (keep_paths) { - processObjects(LPE_TO_OBJECTS); - items.clear(); - return; - } - if (sp_lpe_item->countLPEOfType(SLICE) == 1) { - processObjects(LPE_ERASE); - } else { - for (auto item: items) { - SPItem *extraitem = dynamic_cast(getSPDoc()->getObjectById(item.c_str())); - if (extraitem) { - extraitem->setHidden(true); + auto hreflist = getLPEObj()->hrefList; + if (hreflist.size()) { + sp_lpe_item = dynamic_cast(hreflist.back()); + if (sp_lpe_item) { + items.clear(); + Glib::ustring theclass = sp_lpe_item->getId(); + theclass += "-slice"; + for (auto item : getSPDoc()->getObjectsByClass(theclass)) { + items.emplace_back(item->getId()); + } + if (keep_paths) { + processObjects(LPE_TO_OBJECTS); + items.clear(); + return; + } + if (sp_lpe_item->countLPEOfType(SLICE) == 1) { + processObjects(LPE_ERASE); + } else { + for (auto item: items) { + SPItem *extraitem = dynamic_cast(getSPDoc()->getObjectById(item.c_str())); + if (extraitem) { + extraitem->setHidden(true); + } + } } } } -- GitLab