From cd31d0e698314bab5228c51850e2f5de04988a5f Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 18 Feb 2025 14:47:03 +0100 Subject: [PATCH] TD: Fix crash on selecting 3D edge for dimension Unlike in the bug description of issue 19654 the user doesn't have to preselect an edge in the 3D view but first start the dimension command and then select an edge. This commit adds some security checks to TechDrawHandler::quit(), TechDrawHandler::getPage() and TDHandlerDimension::onSelectionChanged() to be on the safe side that no null pointers are dereferenced. But the ultimative fix for this whole problem is to change activateHandler() and immediately delete the passed TechDrawHandler if it fails to find the appropriate QGVPage. This is needed as otherwise the handler behaves like a ghost object that affects the selection mechanism and disallows to select anything in the 3D view or the tree view. Fixes issue 19654 --- src/Mod/TechDraw/Gui/CommandCreateDims.cpp | 9 +++++++-- src/Mod/TechDraw/Gui/TechDrawHandler.cpp | 8 +++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 1351041e06..42a0d6f4d3 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -120,6 +120,7 @@ void positionDimText(DrawViewDimension* dim, int indexOffset = 0); void activateHandler(TechDrawHandler* newHandler) { + std::unique_ptr ptr(newHandler); auto* mdi = qobject_cast(Gui::getMainWindow()->activeWindow()); if (!mdi) { return; @@ -134,7 +135,7 @@ void activateHandler(TechDrawHandler* newHandler) if (!viewPage) { return; } - viewPage->activateHandler(newHandler); + viewPage->activateHandler(ptr.release()); } //=========================================================================== @@ -517,8 +518,12 @@ public: return; } + App::Document* pageDoc = nullptr; + if (auto page = getPage()) { + pageDoc = page->getDocument(); + } if (msg.Object.getObjectName().empty() - || msg.Object.getDocument() != getPage()->getDocument()) { + || (msg.Object.getDocument() != pageDoc)) { if (msg.Type == Gui::SelectionChanges::AddSelection) { Gui::Selection().rmvSelection(msg.pDocName, msg.pObjectName, msg.pSubName); } diff --git a/src/Mod/TechDraw/Gui/TechDrawHandler.cpp b/src/Mod/TechDraw/Gui/TechDrawHandler.cpp index bd182c4497..9e06322220 100644 --- a/src/Mod/TechDraw/Gui/TechDrawHandler.cpp +++ b/src/Mod/TechDraw/Gui/TechDrawHandler.cpp @@ -109,7 +109,9 @@ void TechDrawHandler::mouseReleaseEvent(QMouseEvent* event) void TechDrawHandler::quit() { - viewPage->deactivateHandler(); + if (viewPage) { + viewPage->deactivateHandler(); + } } QWidget* TechDrawHandler::getCursorWidget() @@ -127,5 +129,5 @@ void TechDrawHandler::setWidgetCursor(QCursor cursor) TechDraw::DrawPage* TechDrawHandler::getPage() { - return viewPage->getDrawPage(); -} \ No newline at end of file + return viewPage ? viewPage->getDrawPage() : nullptr; +}