From 395a0144e75c772c665c3808fbb9ec32aeabeabf Mon Sep 17 00:00:00 2001 From: "hermes@bounty.hunter" Date: Fri, 29 May 2026 02:07:09 +0700 Subject: [PATCH] fix: resolve bounty issue #732 Root cause: - NoteListDelegateEditor destructor calls unsetEditorWidget(m_id, nullptr) - unsetEditorWidget was accessing m_openedEditor using operator[] which can cause detachment and re-allocation during destruction - closeAllEditor() was called after model() might already be destroyed Fix: - Skip nullptr removal in unsetEditorWidget (no-op anyway) - Use iterator-based access instead of operator[] to avoid detachment - Add model() validity check in closeAllEditor() before iterating - Clear m_openedEditor early if model is already destroyed --- src/notelistview.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/notelistview.cpp b/src/notelistview.cpp index 163c8225..e92776c8 100644 --- a/src/notelistview.cpp +++ b/src/notelistview.cpp @@ -193,13 +193,24 @@ void NoteListView::setEditorWidget(int noteId, QWidget *w) void NoteListView::unsetEditorWidget(int noteId, QWidget *w) { - if (m_openedEditor.contains(noteId)) { - m_openedEditor[noteId].removeAll(w); + // Skip if trying to remove nullptr - this is a no-op and can cause + // issues during destruction when the map state may be inconsistent + if (w == nullptr) { + return; + } + auto it = m_openedEditor.find(noteId); + if (it != m_openedEditor.end()) { + it.value().removeAll(w); } } void NoteListView::closeAllEditor() { + // Check if model is still valid before iterating + if (!model()) { + m_openedEditor.clear(); + return; + } for (const auto &id : m_openedEditor.keys()) { auto index = static_cast(model())->getNoteIndex(id); closePersistentEditor(index);