Commit 95bed157 authored by Friedrich W. H. Kossebau's avatar Friedrich W. H. Kossebau
Browse files

Merge branch '5.3'

parents 82ff401c d940a88e
......@@ -86,8 +86,11 @@ public:
~TextDocumentPrivate()
{
delete addedContextMenu;
addedContextMenu = nullptr;
// Handle the case we are being deleted while the context menu is not yet hidden.
// We want to remove all actions we added to it, especially those not owned by the document
// but by the plugins (i.e. created on-the-fly during ContextMenuExtension::populateMenu
// with ownership set to our addedContextMenu)
cleanContextMenu();
saveSessionConfig();
delete document;
......@@ -224,6 +227,31 @@ public:
setStatus(document, dirty);
}
void cleanContextMenu()
{
if (!addedContextMenu) {
return;
}
if (currentContextMenu) {
const auto actions = addedContextMenu->actions();
for (QAction* action : actions) {
currentContextMenu->removeAction(action);
}
currentContextMenu.clear();
}
// The addedContextMenu owns those actions created on-the-fly for the context menu
// (other than those actions only shared for the context menu, but also used elsewhere)
// and thuse deletes then on its own destruction.
// Some actions potentially could be connected to triggered-signal handlers
// using Qt::QueuedConnection (at least SwitchToBuddyPlugin does so currently).
// Deleting them here also would also delete the connection before the handler is triggered.
// So we delay the menu's and thus their destruction to the next eventloop by default.
addedContextMenu->deleteLater();
addedContextMenu = nullptr;
}
TextDocument * const q;
QPointer<KTextEditor::Document> document;
......@@ -232,6 +260,7 @@ public:
bool loaded = false;
// we want to remove the added stuff when the menu hides
QMenu* addedContextMenu = nullptr;
QPointer<QMenu> currentContextMenu;
};
class TextViewPrivate
......@@ -720,18 +749,29 @@ void KDevelop::TextDocument::textChanged(KTextEditor::Document *document)
notifyContentChanged();
}
void KDevelop::TextDocument::unpopulateContextMenu()
{
Q_D(TextDocument);
auto* menu = qobject_cast<QMenu*>(sender());
disconnect(menu, &QMenu::aboutToHide, this, &TextDocument::unpopulateContextMenu);
d->cleanContextMenu();
}
void KDevelop::TextDocument::populateContextMenu( KTextEditor::View* v, QMenu* menu )
{
Q_D(TextDocument);
if (d->addedContextMenu) {
const auto actions = d->addedContextMenu->actions();
for (QAction* action : actions) {
menu->removeAction(action);
}
delete d->addedContextMenu;
qCWarning(SHELL) << "populateContextMenu() called while we still handled another menu.";
d->cleanContextMenu();
}
d->currentContextMenu = menu;
connect(menu, &QMenu::aboutToHide, this, &TextDocument::unpopulateContextMenu);
d->addedContextMenu = new QMenu();
EditorContext c(v, v->cursorPosition());
......
......@@ -89,6 +89,7 @@ private:
void newDocumentStatus(KTextEditor::Document*);
void populateContextMenu(KTextEditor::View*, QMenu*);
void unpopulateContextMenu();
void textChanged(KTextEditor::Document*);
void documentUrlChanged(KTextEditor::Document*);
void slotDocumentLoaded();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment