Editors: Fix crash after triggering dropdown menu after closing editor

The context menu kept a handle on the editor and document, and these
could be deleted behind its back. Use QPointers to actually check.

Fixes: QTCREATORBUG-31232
Change-Id: I613abbe6dc0fbac60c2e527f715a7b8c2f083893
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Eike Ziller
2024-07-12 14:53:34 +02:00
parent f2a5c6f0ce
commit 8758c3c8dd
2 changed files with 18 additions and 15 deletions

View File

@@ -539,12 +539,12 @@ void EditorManagerPrivate::init()
this, &EditorManagerPrivate::closeAllEditorsExceptVisible); this, &EditorManagerPrivate::closeAllEditorsExceptVisible);
connect(m_openGraphicalShellContextAction, &QAction::triggered, this, [this] { connect(m_openGraphicalShellContextAction, &QAction::triggered, this, [this] {
if (!m_contextMenuEntry || m_contextMenuEntry->filePath().isEmpty()) if (!m_contextMenuDocument || m_contextMenuEntry->filePath().isEmpty())
return; return;
FileUtils::showInGraphicalShell(ICore::dialogParent(), m_contextMenuEntry->filePath()); FileUtils::showInGraphicalShell(ICore::dialogParent(), m_contextMenuEntry->filePath());
}); });
connect(m_showInFileSystemViewContextAction, &QAction::triggered, this, [this] { connect(m_showInFileSystemViewContextAction, &QAction::triggered, this, [this] {
if (!m_contextMenuEntry || m_contextMenuEntry->filePath().isEmpty()) if (!m_contextMenuDocument || m_contextMenuEntry->filePath().isEmpty())
return; return;
FileUtils::showInFileSystemView(m_contextMenuEntry->filePath()); FileUtils::showInFileSystemView(m_contextMenuEntry->filePath());
}); });
@@ -552,7 +552,7 @@ void EditorManagerPrivate::init()
connect(m_findInDirectoryAction, &QAction::triggered, connect(m_findInDirectoryAction, &QAction::triggered,
this, &EditorManagerPrivate::findInDirectory); this, &EditorManagerPrivate::findInDirectory);
connect(m_filePropertiesAction, &QAction::triggered, this, [this] { connect(m_filePropertiesAction, &QAction::triggered, this, [this] {
if (!m_contextMenuEntry || m_contextMenuEntry->filePath().isEmpty()) if (!m_contextMenuDocument || m_contextMenuEntry->filePath().isEmpty())
return; return;
DocumentManager::showFilePropertiesDialog(m_contextMenuEntry->filePath()); DocumentManager::showFilePropertiesDialog(m_contextMenuEntry->filePath());
}); });
@@ -2402,14 +2402,14 @@ void EditorManagerPrivate::handleContextChange(const QList<IContext *> &context)
void EditorManagerPrivate::copyFilePathFromContextMenu() void EditorManagerPrivate::copyFilePathFromContextMenu()
{ {
if (!d->m_contextMenuEntry) if (!d->m_contextMenuDocument)
return; return;
setClipboardAndSelection(d->m_contextMenuEntry->filePath().toUserOutput()); setClipboardAndSelection(d->m_contextMenuEntry->filePath().toUserOutput());
} }
void EditorManagerPrivate::copyLocationFromContextMenu() void EditorManagerPrivate::copyLocationFromContextMenu()
{ {
if (!d->m_contextMenuEntry) if (!d->m_contextMenuDocument)
return; return;
const QString text = d->m_contextMenuEntry->filePath().toUserOutput() const QString text = d->m_contextMenuEntry->filePath().toUserOutput()
+ QLatin1Char(':') + m_copyLocationContextAction->data().toString(); + QLatin1Char(':') + m_copyLocationContextAction->data().toString();
@@ -2418,28 +2418,28 @@ void EditorManagerPrivate::copyLocationFromContextMenu()
void EditorManagerPrivate::copyFileNameFromContextMenu() void EditorManagerPrivate::copyFileNameFromContextMenu()
{ {
if (!d->m_contextMenuEntry) if (!d->m_contextMenuDocument)
return; return;
setClipboardAndSelection(d->m_contextMenuEntry->filePath().fileName()); setClipboardAndSelection(d->m_contextMenuEntry->filePath().fileName());
} }
void EditorManagerPrivate::saveDocumentFromContextMenu() void EditorManagerPrivate::saveDocumentFromContextMenu()
{ {
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : nullptr; IDocument *document = d->m_contextMenuDocument.get();
if (document) if (document)
saveDocument(document); saveDocument(document);
} }
void EditorManagerPrivate::saveDocumentAsFromContextMenu() void EditorManagerPrivate::saveDocumentAsFromContextMenu()
{ {
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : nullptr; IDocument *document = d->m_contextMenuDocument.get();
if (document) if (document)
saveDocumentAs(document); saveDocumentAs(document);
} }
void EditorManagerPrivate::revertToSavedFromContextMenu() void EditorManagerPrivate::revertToSavedFromContextMenu()
{ {
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : nullptr; IDocument *document = d->m_contextMenuDocument.get();
if (document) if (document)
revertToSaved(document); revertToSaved(document);
} }
@@ -2449,7 +2449,7 @@ void EditorManagerPrivate::closeEditorFromContextMenu()
if (d->m_contextMenuEditor) { if (d->m_contextMenuEditor) {
closeEditorOrDocument(d->m_contextMenuEditor); closeEditorOrDocument(d->m_contextMenuEditor);
} else { } else {
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : nullptr; IDocument *document = d->m_contextMenuDocument.get();
if (document) if (document)
EditorManager::closeDocuments({document}); EditorManager::closeDocuments({document});
} }
@@ -2457,7 +2457,7 @@ void EditorManagerPrivate::closeEditorFromContextMenu()
void EditorManagerPrivate::closeOtherDocumentsFromContextMenu() void EditorManagerPrivate::closeOtherDocumentsFromContextMenu()
{ {
IDocument *document = d->m_contextMenuEntry ? d->m_contextMenuEntry->document : nullptr; IDocument *document = d->m_contextMenuDocument.get();
EditorManager::closeOtherDocuments(document); EditorManager::closeOtherDocuments(document);
} }
@@ -2613,14 +2613,14 @@ void EditorManagerPrivate::autoSuspendDocuments()
void EditorManagerPrivate::openTerminal() void EditorManagerPrivate::openTerminal()
{ {
if (!d->m_contextMenuEntry || d->m_contextMenuEntry->filePath().isEmpty()) if (!d->m_contextMenuDocument || d->m_contextMenuEntry->filePath().isEmpty())
return; return;
FileUtils::openTerminal(d->m_contextMenuEntry->filePath().parentDir(), {}); FileUtils::openTerminal(d->m_contextMenuEntry->filePath().parentDir(), {});
} }
void EditorManagerPrivate::findInDirectory() void EditorManagerPrivate::findInDirectory()
{ {
if (!d->m_contextMenuEntry || d->m_contextMenuEntry->filePath().isEmpty()) if (!d->m_contextMenuDocument || d->m_contextMenuEntry->filePath().isEmpty())
return; return;
const FilePath path = d->m_contextMenuEntry->filePath(); const FilePath path = d->m_contextMenuEntry->filePath();
emit m_instance->findOnFileSystemRequest( emit m_instance->findOnFileSystemRequest(
@@ -2629,7 +2629,7 @@ void EditorManagerPrivate::findInDirectory()
void EditorManagerPrivate::togglePinned() void EditorManagerPrivate::togglePinned()
{ {
if (!d->m_contextMenuEntry || d->m_contextMenuEntry->filePath().isEmpty()) if (!d->m_contextMenuDocument || d->m_contextMenuEntry->filePath().isEmpty())
return; return;
const bool currentlyPinned = d->m_contextMenuEntry->pinned; const bool currentlyPinned = d->m_contextMenuEntry->pinned;
@@ -2832,6 +2832,7 @@ void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentMod
{ {
QTC_ASSERT(contextMenu, return); QTC_ASSERT(contextMenu, return);
d->m_contextMenuEntry = entry; d->m_contextMenuEntry = entry;
d->m_contextMenuDocument = entry ? entry->document : nullptr;
d->m_contextMenuEditor = editor; d->m_contextMenuEditor = editor;
const FilePath filePath = entry ? entry->filePath() : FilePath(); const FilePath filePath = entry ? entry->filePath() : FilePath();
@@ -2911,6 +2912,7 @@ void EditorManager::addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentM
{ {
QTC_ASSERT(contextMenu, return); QTC_ASSERT(contextMenu, return);
d->m_contextMenuEntry = entry; d->m_contextMenuEntry = entry;
d->m_contextMenuDocument = entry ? entry->document : nullptr;
bool enabled = entry && !entry->filePath().isEmpty(); bool enabled = entry && !entry->filePath().isEmpty();
d->m_openGraphicalShellContextAction->setEnabled(enabled); d->m_openGraphicalShellContextAction->setEnabled(enabled);
d->m_showInFileSystemViewContextAction->setEnabled(enabled); d->m_showInFileSystemViewContextAction->setEnabled(enabled);

View File

@@ -250,7 +250,8 @@ private:
QAction *m_filePropertiesAction = nullptr; QAction *m_filePropertiesAction = nullptr;
QAction *m_pinAction = nullptr; QAction *m_pinAction = nullptr;
DocumentModel::Entry *m_contextMenuEntry = nullptr; DocumentModel::Entry *m_contextMenuEntry = nullptr;
IEditor *m_contextMenuEditor = nullptr; QPointer<IDocument> m_contextMenuDocument;
QPointer<IEditor> m_contextMenuEditor;
OpenEditorsWindow *m_windowPopup = nullptr; OpenEditorsWindow *m_windowPopup = nullptr;