Tue, 28 Sep 2021 22:14:00 +0300
Fix memory corruption involving document tools.
I don't think that the metaobject-initialization had anything to do with this
but it is a lot simpler without it anyway.
--- a/src/document.cpp Tue Sep 28 00:21:09 2021 +0300 +++ b/src/document.cpp Tue Sep 28 22:14:00 2021 +0300 @@ -27,12 +27,6 @@ #include "tools/selecttool.h" #include "tools/transformtool.h" -static const QMetaObject* const toolMetaObjects[] = { - &SelectTool::staticMetaObject, - &DrawTool::staticMetaObject, - &TransformTool::staticMetaObject, -}; - Document::Document( Model* model, DocumentManager* documents, @@ -158,32 +152,27 @@ void Document::initializeTools() { - for (const QMetaObject* const metaObject : ::toolMetaObjects) + this->tools.clear(); + this->tools.reserve(3); + this->tools.push_back(new SelectTool{this->model, this}); + this->tools.push_back(new DrawTool{this->model, this}); + this->tools.push_back(new TransformTool{this->model, this}); + for (BaseTool* const toolInstance : this->tools) { - QObject* const objectInstance = metaObject->newInstance(Q_ARG(Model*, this->model), Q_ARG(QObject*, this)); - BaseTool* const toolInstance = qobject_cast<BaseTool*>(objectInstance); - if (toolInstance) + QAction* action = new QAction{toolInstance->name(), this}; + action->setCheckable(true); + this->toolActions[toolInstance] = action; + action->setToolTip(toolInstance->toolTip()); + connect(action, &QAction::triggered, this, &Document::toolActionTriggered); + this->toolsBar->addAction(action); + QWidget* const widget = toolInstance->toolWidget(); + if (widget) { - this->tools.append(toolInstance); - QAction* action = new QAction{toolInstance->name(), this}; - action->setCheckable(true); - this->toolActions[toolInstance] = action; - action->setToolTip(toolInstance->toolTip()); - connect(action, &QAction::triggered, this, &Document::toolActionTriggered); - this->toolsBar->addAction(action); - QWidget* const widget = toolInstance->toolWidget(); - if (widget) - { - this->ui.toolWidgetStack->addWidget(widget); - } - else - { - this->ui.toolWidgetStack->addWidget(new QWidget{this}); - } + this->ui.toolWidgetStack->addWidget(widget); } else { - QMessageBox::critical(this, tr("Error"), tr("Unable to construct %1").arg(metaObject->className())); + this->ui.toolWidgetStack->addWidget(new QWidget{this}); } } this->selectTool(this->tools[0]);
--- a/src/document.h Tue Sep 28 00:21:09 2021 +0300 +++ b/src/document.h Tue Sep 28 22:14:00 2021 +0300 @@ -74,5 +74,5 @@ /** * @brief History information of edits to this model */ - EditHistory editHistory; + // EditHistory editHistory; };
--- a/src/tools/basetool.cpp Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/basetool.cpp Tue Sep 28 22:14:00 2021 +0300 @@ -1,4 +1,5 @@ #include "basetool.h" -BaseTool::BaseTool(Model*, QObject* parent) : - QObject{parent} {} +BaseTool::BaseTool(Model*, QWidget *parent) : + QObject{parent}, + parentWidget{parent} {}
--- a/src/tools/basetool.h Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/basetool.h Tue Sep 28 22:14:00 2021 +0300 @@ -10,7 +10,7 @@ Q_OBJECT public: - BaseTool(Model* model, QObject* parent = nullptr); + BaseTool(Model* model, QWidget* parent = nullptr); virtual QString name() const = 0; virtual QString toolTip() const = 0; @@ -22,5 +22,7 @@ virtual void selectionChanged(const QSet<ldraw::id_t>&) {} virtual void reset() {} virtual void overpaint(Canvas*, QPainter*) const {} +protected: + QWidget* const parentWidget; };
--- a/src/tools/drawtool.cpp Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/drawtool.cpp Tue Sep 28 22:14:00 2021 +0300 @@ -12,7 +12,7 @@ static const QBrush polygonBrush = {QColor{64, 255, 128, 192}}; static const QBrush badPolygonBrush = {QColor{255, 96, 96, 192}}; -DrawTool::DrawTool(Model *model, QObject *parent) : +DrawTool::DrawTool(Model *model, QWidget *parent) : BaseTool{model, parent} {} QString DrawTool::name() const
--- a/src/tools/drawtool.h Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/drawtool.h Tue Sep 28 22:14:00 2021 +0300 @@ -6,7 +6,7 @@ Q_OBJECT public: - Q_INVOKABLE DrawTool(Model* model, QObject* parent = nullptr); + Q_INVOKABLE DrawTool(Model* model, QWidget* parent = nullptr); QString name() const override; QString toolTip() const override;
--- a/src/tools/selecttool.cpp Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/selecttool.cpp Tue Sep 28 22:14:00 2021 +0300 @@ -1,8 +1,8 @@ #include "selecttool.h" -SelectTool::SelectTool(Model* model, QObject* parent) : +SelectTool::SelectTool(Model* model, QWidget* parent) : BaseTool{model, parent}, - objectEditor{model, ldraw::NULL_ID, nullptr} {} + objectEditor{new ObjectEditor{model, ldraw::NULL_ID, parent}} {} QString SelectTool::name() const { @@ -37,17 +37,17 @@ QWidget* SelectTool::toolWidget() { - return &this->objectEditor; + return this->objectEditor; } void SelectTool::selectionChanged(const QSet<ldraw::id_t>& newSelection) { if (newSelection.size() == 1) { - this->objectEditor.setObjectId(*newSelection.begin()); + this->objectEditor->setObjectId(*newSelection.begin()); } else { - this->objectEditor.setObjectId(ldraw::NULL_ID); + this->objectEditor->setObjectId(ldraw::NULL_ID); } }
--- a/src/tools/selecttool.h Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/selecttool.h Tue Sep 28 22:14:00 2021 +0300 @@ -7,12 +7,11 @@ Q_OBJECT public: - Q_INVOKABLE SelectTool(Model* model, QObject* parent = nullptr); - + Q_INVOKABLE SelectTool(Model* model, QWidget* parent = nullptr); QString name() const override; QString toolTip() const override; bool mouseClick(Document*, Canvas*, QMouseEvent*) override; QWidget* toolWidget() override; void selectionChanged(const QSet<ldraw::id_t> &newSelection) override; - ObjectEditor objectEditor; + ObjectEditor* objectEditor; };
--- a/src/tools/transformtool.cpp Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/transformtool.cpp Tue Sep 28 22:14:00 2021 +0300 @@ -4,24 +4,19 @@ #include "linetypes/object.h" #include "transformtool.h" -TransformTool::TransformTool(Model* model, QObject* parent) : +TransformTool::TransformTool(Model* model, QWidget* parent) : BaseTool{model, parent}, model{model}, - button{new QPushButton{"Apply"}}, - widget{new QWidget} + matrixEditor{new MatrixEditor{parent}}, + button{new QPushButton{"Apply", parent}}, + widget{new QWidget{parent}} { widget->setLayout(new QHBoxLayout{widget}); - widget->layout()->addWidget(&this->matrixEditor); + widget->layout()->addWidget(this->matrixEditor); widget->layout()->addWidget(button); connect(button, &QPushButton::clicked, this, &TransformTool::applyButtonClicked); } -TransformTool::~TransformTool() -{ - delete this->widget; - delete this->button; -} - QString TransformTool::name() const { return "Transform"; @@ -45,7 +40,7 @@ void TransformTool::applyButtonClicked() { Model::EditContext editcontext = this->model->edit(); - const glm::mat4 matrix = this->matrixEditor.value(); + const glm::mat4 matrix = this->matrixEditor->value(); for (ldraw::id_t id : this->selection) { const ldraw::Object* object = model->get(id);
--- a/src/tools/transformtool.h Tue Sep 28 00:21:09 2021 +0300 +++ b/src/tools/transformtool.h Tue Sep 28 22:14:00 2021 +0300 @@ -7,8 +7,7 @@ { Q_OBJECT public: - Q_INVOKABLE TransformTool(Model *model, QObject *parent = nullptr); - ~TransformTool(); + Q_INVOKABLE TransformTool(Model *model, QWidget *parent = nullptr); virtual QString name() const override; virtual QString toolTip() const override; void selectionChanged(const QSet<ldraw::id_t> &newSelection) override; @@ -16,7 +15,7 @@ private: Q_SLOT void applyButtonClicked(); Model* const model; - MatrixEditor matrixEditor; + MatrixEditor* matrixEditor; QPushButton* button; QWidget* widget; QSet<ldraw::id_t> selection;