TechDraw: Return text fields directly as childs of QGISVGTemplate
As the title says. I've noticed during reproducing of #18921, that after in `PagePrinter::renderPage` we call `setTemplateMarkers` twice, which results in deleting `childItems` allocated memory (in `setTemplateMarkers`->`setMarkers`->`updateView`->`clearClickHandles`), and then we are calling `setTemplateMarkers` (also in `PagePrinter::renderPage`) second time, accessing `textFields` in `setMarkers` method, which still contain hanging pointers from the previous deallocation. This results in segfaults as we iterate through `textFields`. So, instead of keeping sychronization between childs of QGISVGTemplate and textFields vector - this patch removes this variable at all and uses childs directly to return text fields.
This commit is contained in:
@@ -204,17 +204,30 @@ void QGISVGTemplate::updateView(bool update)
|
||||
draw();
|
||||
}
|
||||
|
||||
std::vector<TemplateTextField*> QGISVGTemplate::getTextFields()
|
||||
{
|
||||
constexpr int TemplateTextFieldType {QGraphicsItem::UserType + 160};
|
||||
std::vector<TemplateTextField*> result;
|
||||
result.reserve(childItems().size());
|
||||
|
||||
QList<QGraphicsItem*> templateChildren = childItems();
|
||||
for (auto& child : templateChildren) {
|
||||
if (child->type() == TemplateTextFieldType) {
|
||||
result.push_back(dynamic_cast<TemplateTextField*>(child));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QGISVGTemplate::clearClickHandles()
|
||||
{
|
||||
prepareGeometryChange();
|
||||
constexpr int TemplateTextFieldType{QGraphicsItem::UserType + 160};
|
||||
auto templateChildren = childItems();
|
||||
for (auto& child : templateChildren) {
|
||||
if (child->type() == TemplateTextFieldType) {
|
||||
child->hide();
|
||||
scene()->removeItem(child);
|
||||
delete child;
|
||||
}
|
||||
std::vector<TemplateTextField*> textFields = getTextFields();
|
||||
for (auto& textField : textFields) {
|
||||
textField->hide();
|
||||
scene()->removeItem(textField);
|
||||
delete textField;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +330,6 @@ void QGISVGTemplate::createClickHandles()
|
||||
item->setZValue(ZVALUE::SVGTEMPLATE + 1);
|
||||
|
||||
addToGroup(item);
|
||||
textFields.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
void updateView(bool update = false) override;
|
||||
|
||||
TechDraw::DrawSVGTemplate* getSVGTemplate();
|
||||
std::vector<TemplateTextField*> getTextFields() override;
|
||||
|
||||
protected:
|
||||
void openFile(const QFile& file);
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
inline qreal getY() { return y() * -1; }
|
||||
|
||||
virtual void updateView(bool update = false);
|
||||
std::vector<TemplateTextField *> getTextFields() { return textFields; };
|
||||
virtual std::vector<TemplateTextField *> getTextFields() { return textFields; };
|
||||
|
||||
virtual void draw() = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user