Fix the crash described in #12785

Closes #12785. The cause of the segmentation fault is access to the
already deleted _QMenu_. Simple setting attribute `Qt::WA_DeleteOnClose`
and removal of `delete menu` prevented it. To reproduce the crash, one
needs to mess up the `user.cfg` file in the way described in the issue.

Here is the fragment from the issue to mess up the `user.cfg` file:

```xml
<FCParamGroup Name="Expression">
<FCText Name="EditorTrigger">=</FCText>
<FCBool Name="AntoHideEditorIcon" Value="1"/>
<FCBool Name="NoSystemBackground" Value="1"/>
<FCInt Name="EditDialogBGAlpha" Value="1"/>
<FCInt Name="EditDialogWidth" Value="300"/>
<FCInt Name="EditDialogHeight" Value="214"/>
<FCInt Name="EditDialogTextHeight" Value="35"/>
</FCParamGroup>
```

---

This commit changes also unconnected things:

- usage of `QObject::connect` instead of if statements
- relocation of a separator and an action inside the if statement (I saw
no reason to have a separator and an action for _ExpressionCompleter_ if
there is no expression completer)
- usage of asynchronous `QMenu::popup()` instead of synchronous
`QMenu::exec()`. This way is used within [the source code of Qt]
(https://github.com/qt/qtbase/blob/5.15/src/widgets/widgets/
qlineedit.cpp#L2191-L2197).
This commit is contained in:
xtemp09
2024-03-08 20:00:00 +07:00
committed by wwmayer
parent 7212cccae5
commit a3036d16f1

View File

@@ -959,25 +959,18 @@ void ExpressionLineEdit::keyPressEvent(QKeyEvent* e)
void ExpressionLineEdit::contextMenuEvent(QContextMenuEvent* event)
{
QMenu* menu = createStandardContextMenu();
menu->addSeparator();
QAction* match = menu->addAction(tr("Exact match"));
if (completer) {
menu->addSeparator();
QAction *match = menu->addAction(tr("Exact match"));
match->setCheckable(true);
match->setChecked(completer->filterMode() == Qt::MatchStartsWith);
QObject::connect(match, &QAction::toggled,
this, &Gui::ExpressionLineEdit::setExactMatch);
}
else {
match->setVisible(false);
}
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* action = menu->exec(event->globalPos());
if (completer) {
if (action == match)
setExactMatch(match->isChecked());
}
delete menu;
menu->popup(event->globalPos());
}