From 477040c0b2277e6f10fda70ed6f38f186cc2fc43 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 14 Nov 2019 10:52:07 +0200 Subject: [PATCH] Fix crash. When a user calls full parse and a pattern contains a lot of pieces while they update a second call may cause a crash. --HG-- branch : develop --- src/app/valentina/xml/vpattern.cpp | 33 ++++++++++++++++++++++++------ src/app/valentina/xml/vpattern.h | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index c75fbd324..ecd491a85 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -59,6 +59,12 @@ #include "../vpatterndb/vpiecepath.h" #include "../vpatterndb/vnodedetail.h" +#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) +#include "../vmisc/backport/qscopeguard.h" +#else +#include +#endif + #include #include #include @@ -102,7 +108,7 @@ QString DefLabelLanguage() //--------------------------------------------------------------------------------------------------------------------- VPattern::VPattern(VContainer *data, VMainGraphicsScene *sceneDraw, VMainGraphicsScene *sceneDetail, QObject *parent) - : VAbstractPattern(parent), data(data), sceneDraw(sceneDraw), sceneDetail(sceneDetail), updatePieces() + : VAbstractPattern(parent), data(data), sceneDraw(sceneDraw), sceneDetail(sceneDetail) { SCASSERT(sceneDraw != nullptr) SCASSERT(sceneDetail != nullptr) @@ -851,7 +857,7 @@ void VPattern::ParseDetailElement(QDomElement &domElement, const Document &parse VToolSeamAllowance *piece = VToolSeamAllowance::Create(initData); if (parse == Document::FullParse) { - updatePieces.append(piece); + updatePieces.append(piece->getId()); } //Rewrite attribute formula. Need for situation when we have wrong formula. if (w != initData.width) @@ -3569,19 +3575,36 @@ quint32 VPattern::LastToolId() const //--------------------------------------------------------------------------------------------------------------------- void VPattern::RefreshPieceGeometry() { + auto CleanRefreshList = qScopeGuard([this]() + { + updatePieces.clear(); + VMainGraphicsView::NewSceneRect(sceneDetail, qApp->getSceneView()); + }); + if (qApp->IsGUIMode() && m_parsing) { return; } - for(auto piece : qAsConst(updatePieces)) + for(auto pieceId : qAsConst(updatePieces)) { if (qApp->IsGUIMode() && m_parsing) { return; } - piece->RefreshGeometry(); + try + { + if (VToolSeamAllowance *piece = qobject_cast(VAbstractPattern::getTool(pieceId))) + { + piece->RefreshGeometry(); + } + } + catch(const VExceptionBadId &) + { + // do nothing + } + QApplication::processEvents(); if (qApp->IsGUIMode() && m_parsing) @@ -3589,8 +3612,6 @@ void VPattern::RefreshPieceGeometry() return; } } - updatePieces.clear(); - VMainGraphicsView::NewSceneRect(sceneDetail, qApp->getSceneView()); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/valentina/xml/vpattern.h b/src/app/valentina/xml/vpattern.h index cc115f7f3..4d6cfea6f 100644 --- a/src/app/valentina/xml/vpattern.h +++ b/src/app/valentina/xml/vpattern.h @@ -136,7 +136,7 @@ private: VMainGraphicsScene *sceneDraw; VMainGraphicsScene *sceneDetail; - QVector updatePieces; + QVector updatePieces{}; /** * @brief m_parsing true if parsing a pattern. Helps to stop updating piece when new parsing happend before