From e6a98f368e54fbd067083635b511f333341ef9b6 Mon Sep 17 00:00:00 2001
From: hjk <hjk@theqtcompany.com>
Date: Wed, 26 Aug 2015 14:39:15 +0200
Subject: [PATCH] Core: Replace ICoreListener by std::functions

ICoreListener::coreAboutToClose() remains in the core,
ICoreListener::editorAboutToClose() is handled by a new
EditorManager::addCloseEditorListener() function.

This removes the need for some boiler plate code resulting
from the need to implement the interface in custom classes
(DesignModeCoreListener, EditorClosingCoreListener,
PojectEplorer::CoreListener and VcsBase::CoreListener).

EditorManager::addCloseEditorListener

Change-Id: Ie554c987b5455b555be6d77b77e4013639201d22
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
---
 src/plugins/coreplugin/coreplugin.pro         |  2 -
 src/plugins/coreplugin/coreplugin.qbs         |  1 -
 src/plugins/coreplugin/designmode.cpp         | 60 ++++--------------
 .../editormanager/editormanager.cpp           | 53 +++++++---------
 .../coreplugin/editormanager/editormanager.h  |  1 +
 .../editormanager/editormanager_p.h           |  3 +-
 src/plugins/coreplugin/icore.cpp              | 17 +++++
 src/plugins/coreplugin/icore.h                |  4 ++
 src/plugins/coreplugin/icorelistener.cpp      | 59 -----------------
 src/plugins/coreplugin/icorelistener.h        | 53 ----------------
 src/plugins/coreplugin/mainwindow.cpp         | 12 ++--
 src/plugins/coreplugin/mainwindow.h           |  5 ++
 .../corelistenercheckingforrunningbuild.cpp   | 47 --------------
 .../corelistenercheckingforrunningbuild.h     | 52 ---------------
 .../projectexplorer/projectexplorer.cpp       |  4 +-
 src/plugins/projectexplorer/projectexplorer.h |  4 +-
 .../projectexplorer/projectexplorer.pro       |  2 -
 .../projectexplorer/projectexplorer.qbs       |  1 -
 src/plugins/vcsbase/corelistener.cpp          | 63 -------------------
 src/plugins/vcsbase/corelistener.h            | 57 -----------------
 src/plugins/vcsbase/vcsbase.pro               |  2 -
 src/plugins/vcsbase/vcsbase.qbs               |  2 -
 src/plugins/vcsbase/vcsbaseplugin.cpp         |  3 +-
 src/plugins/vcsbase/vcsplugin.cpp             | 20 +++---
 src/plugins/vcsbase/vcsplugin.h               |  7 ++-
 25 files changed, 89 insertions(+), 445 deletions(-)
 delete mode 100644 src/plugins/coreplugin/icorelistener.cpp
 delete mode 100644 src/plugins/coreplugin/icorelistener.h
 delete mode 100644 src/plugins/projectexplorer/corelistenercheckingforrunningbuild.cpp
 delete mode 100644 src/plugins/projectexplorer/corelistenercheckingforrunningbuild.h
 delete mode 100644 src/plugins/vcsbase/corelistener.cpp
 delete mode 100644 src/plugins/vcsbase/corelistener.h

diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro
index de9318feaad..650a91dd3a3 100644
--- a/src/plugins/coreplugin/coreplugin.pro
+++ b/src/plugins/coreplugin/coreplugin.pro
@@ -101,7 +101,6 @@ SOURCES += corejsextensions.cpp \
     removefiledialog.cpp \
     iversioncontrol.cpp \
     dialogs/addtovcsdialog.cpp \
-    icorelistener.cpp \
     ioutputpane.cpp \
     patchtool.cpp \
     windowsupport.cpp \
@@ -177,7 +176,6 @@ HEADERS += corejsextensions.h \
     coreconstants.h \
     iversioncontrol.h \
     ifilewizardextension.h \
-    icorelistener.h \
     versiondialog.h \
     core_global.h \
     statusbarwidget.h \
diff --git a/src/plugins/coreplugin/coreplugin.qbs b/src/plugins/coreplugin/coreplugin.qbs
index bd64e1f3ef7..fd1dc2e92a2 100644
--- a/src/plugins/coreplugin/coreplugin.qbs
+++ b/src/plugins/coreplugin/coreplugin.qbs
@@ -57,7 +57,6 @@ QtcPlugin {
             "helpmanager.cpp", "helpmanager.h",
             "icontext.cpp", "icontext.h",
             "icore.cpp", "icore.h",
-            "icorelistener.cpp", "icorelistener.h",
             "id.cpp", "id.h",
             "idocument.cpp", "idocument.h",
             "idocumentfactory.cpp", "idocumentfactory.h",
diff --git a/src/plugins/coreplugin/designmode.cpp b/src/plugins/coreplugin/designmode.cpp
index f119a29eba8..d935ae81437 100644
--- a/src/plugins/coreplugin/designmode.cpp
+++ b/src/plugins/coreplugin/designmode.cpp
@@ -35,9 +35,7 @@
 #include <coreplugin/modemanager.h>
 #include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/coreconstants.h>
-#include <coreplugin/icorelistener.h>
 #include <coreplugin/editormanager/ieditor.h>
-#include <extensionsystem/pluginmanager.h>
 
 #include <QPointer>
 #include <QStringList>
@@ -49,36 +47,6 @@ static Core::DesignMode *m_instance = 0;
 
 namespace Core {
 
-class EditorManager;
-
-enum {
-    debug = false
-};
-
-namespace Internal {
-
-class DesignModeCoreListener : public ICoreListener
-{
-public:
-    DesignModeCoreListener(DesignMode* mode);
-    bool coreAboutToClose();
-private:
-    DesignMode *m_mode;
-};
-
-DesignModeCoreListener::DesignModeCoreListener(DesignMode *mode) :
-        m_mode(mode)
-{
-}
-
-bool DesignModeCoreListener::coreAboutToClose()
-{
-    m_mode->currentEditorChanged(0);
-    return true;
-}
-
-} // namespace Internal
-
 struct DesignEditorInfo
 {
     int widgetIndex;
@@ -90,10 +58,9 @@ struct DesignEditorInfo
 class DesignModePrivate
 {
 public:
-    explicit DesignModePrivate(DesignMode *q);
+    DesignModePrivate();
 
 public:
-    Internal::DesignModeCoreListener *m_coreListener;
     QPointer<IEditor> m_currentEditor;
     bool m_isActive;
     bool m_isRequired;
@@ -102,18 +69,22 @@ public:
     Context m_activeContext;
 };
 
-DesignModePrivate::DesignModePrivate(DesignMode *q)
-  : m_coreListener(new Internal::DesignModeCoreListener(q)),
-    m_isActive(false),
-    m_isRequired(false),
-    m_stackWidget(new QStackedWidget)
-{
-}
+DesignModePrivate::DesignModePrivate()
+    : m_isActive(false),
+      m_isRequired(false),
+      m_stackWidget(new QStackedWidget)
+{}
 
 DesignMode::DesignMode()
-    : d(new DesignModePrivate(this))
+    : d(new DesignModePrivate)
 {
     m_instance = this;
+
+    ICore::addPreCloseListener([]() -> bool {
+        m_instance->currentEditorChanged(0);
+        return true;
+    });
+
     setObjectName(QLatin1String("DesignMode"));
     setEnabled(false);
     setContext(Context(Constants::C_DESIGN_MODE));
@@ -123,8 +94,6 @@ DesignMode::DesignMode()
     setPriority(Constants::P_MODE_DESIGN);
     setId(Constants::MODE_DESIGN);
 
-    ExtensionSystem::PluginManager::addObject(d->m_coreListener);
-
     connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
             this, &DesignMode::currentEditorChanged);
 
@@ -134,9 +103,6 @@ DesignMode::DesignMode()
 
 DesignMode::~DesignMode()
 {
-    ExtensionSystem::PluginManager::removeObject(d->m_coreListener);
-    delete d->m_coreListener;
-
     qDeleteAll(d->m_editors);
     delete d;
 }
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 9c45744ffe4..b8a2bfbde04 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -51,7 +51,6 @@
 #include <coreplugin/fileutils.h>
 #include <coreplugin/findplaceholder.h>
 #include <coreplugin/icore.h>
-#include <coreplugin/icorelistener.h>
 #include <coreplugin/imode.h>
 #include <coreplugin/infobar.h>
 #include <coreplugin/iversioncontrol.h>
@@ -115,26 +114,6 @@ static const char fileSystemCaseSensitivityKey[] = "Core/FileSystemCaseSensitivi
 
 static const char scratchBufferKey[] = "_q_emScratchBuffer";
 
-//===================EditorClosingCoreListener======================
-
-namespace Core {
-namespace Internal {
-
-class EditorClosingCoreListener : public ICoreListener
-{
-public:
-    bool editorAboutToClose(IEditor *) { return true; }
-    bool coreAboutToClose()
-    {
-        // Do not ask for files to save.
-        // MainWindow::closeEvent has already done that.
-        return EditorManager::closeAllEditors(false);
-    }
-};
-
-} // namespace Internal
-} // namespace Core
-
 using namespace Core;
 using namespace Core::Internal;
 using namespace Utils;
@@ -284,7 +263,6 @@ EditorManagerPrivate::EditorManagerPrivate(QObject *parent) :
     m_openTerminalAction(new QAction(FileUtils::msgTerminalAction(), this)),
     m_findInDirectoryAction(new QAction(FileUtils::msgFindInDirectory(), this)),
     m_windowPopup(0),
-    m_coreListener(0),
     m_reloadSetting(IDocument::AlwaysAsk),
     m_autoSaveEnabled(true),
     m_autoSaveInterval(5),
@@ -297,10 +275,6 @@ EditorManagerPrivate::EditorManagerPrivate(QObject *parent) :
 EditorManagerPrivate::~EditorManagerPrivate()
 {
     if (ICore::instance()) {
-        if (m_coreListener) {
-            ExtensionSystem::PluginManager::removeObject(m_coreListener);
-            delete m_coreListener;
-        }
         ExtensionSystem::PluginManager::removeObject(m_openEditorsFactory);
         delete m_openEditorsFactory;
     }
@@ -516,8 +490,9 @@ void EditorManagerPrivate::init()
     connect(m_autoSaveTimer, SIGNAL(timeout()), SLOT(autoSave()));
     updateAutoSave();
 
-    d->m_coreListener = new EditorClosingCoreListener();
-    ExtensionSystem::PluginManager::addObject(d->m_coreListener);
+    // Do not ask for files to save.
+    // MainWindow::closeEvent has already done that.
+    ICore::addPreCloseListener([]() -> bool { return EditorManager::closeAllEditors(false); });
 
     d->m_openEditorsFactory = new OpenEditorsViewFactory();
     ExtensionSystem::PluginManager::addObject(d->m_openEditorsFactory);
@@ -2351,12 +2326,10 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
     // 2. keep track of the document and all the editors that might remain open for it
     QSet<IEditor*> acceptedEditors;
     QMap<IDocument *, QList<IEditor *> > documentMap;
-    const QList<ICoreListener *> listeners =
-        ExtensionSystem::PluginManager::getObjects<ICoreListener>();
     foreach (IEditor *editor, editorsToClose) {
         bool editorAccepted = true;
-        foreach (ICoreListener *listener, listeners) {
-            if (!listener->editorAboutToClose(editor)) {
+        foreach (const std::function<bool(IEditor*)> listener, d->m_closeEditorListeners) {
+            if (!listener(editor)) {
                 editorAccepted = false;
                 closingFailed = true;
                 break;
@@ -2620,6 +2593,22 @@ bool EditorManager::openExternalEditor(const QString &fileName, Id editorId)
     return ok;
 }
 
+/*!
+    \fn EditorManager::addCloseEditorListener
+
+    \brief The \c EditorManager::addCloseEditorListener function provides
+    a hook for plugins to veto on closing editors.
+
+    When an editor requests a close, all listeners are called. If one of these
+    calls returns \c false, the process is aborted and the event is ignored.
+    If all calls return \c true, \c EditorManager::editorAboutToClose()
+    is emitted and the event is accepted.
+*/
+void EditorManager::addCloseEditorListener(const std::function<bool (IEditor *)> &listener)
+{
+    d->m_closeEditorListeners.append(listener);
+}
+
 QStringList EditorManager::getOpenFileNames()
 {
     QString selectedFilter;
diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index b6b97fd35a9..c105cccfb4b 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -121,6 +121,7 @@ public:
                                            OpenEditorFlags flags = NoFlags);
 
     static bool openExternalEditor(const QString &fileName, Id editorId);
+    static void addCloseEditorListener(const std::function<bool(IEditor *)> &listener);
 
     static QStringList getOpenFileNames();
 
diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h
index 217459e445b..21047095122 100644
--- a/src/plugins/coreplugin/editormanager/editormanager_p.h
+++ b/src/plugins/coreplugin/editormanager/editormanager_p.h
@@ -56,7 +56,6 @@ class EditorManager;
 
 namespace Internal {
 
-class EditorClosingCoreListener;
 class MainWindow;
 class OpenEditorsViewFactory;
 class OpenEditorsWindow;
@@ -243,7 +242,6 @@ private:
     IEditor *m_contextMenuEditor;
 
     OpenEditorsWindow *m_windowPopup;
-    EditorClosingCoreListener *m_coreListener;
 
     QMap<QString, QVariant> m_editorStates;
     OpenEditorsViewFactory *m_openEditorsFactory;
@@ -260,6 +258,7 @@ private:
     int m_bigFileSizeLimitInMB;
 
     QString m_placeholderText;
+    QList<std::function<bool(IEditor *)>> m_closeEditorListeners;
 };
 
 } // Internal
diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp
index c2d18261401..070f384548a 100644
--- a/src/plugins/coreplugin/icore.cpp
+++ b/src/plugins/coreplugin/icore.cpp
@@ -564,6 +564,23 @@ void ICore::openFiles(const QStringList &arguments, ICore::OpenFilesFlags flags)
     m_mainwindow->openFiles(arguments, flags);
 }
 
+
+/*!
+    \fn ICore::addCloseCoreListener
+
+    \brief The \c ICore::addCloseCoreListener function provides a hook for plugins
+    to veto on closing the application.
+
+    When the application window requests a close, all listeners are called.
+    If one if these calls returns \c false, the process is aborted and the
+    event is ignored. If all calls return \c true, \c ICore::coreAboutToClose()
+    is emitted and the event is accepted or performed..
+*/
+void ICore::addPreCloseListener(const std::function<bool ()> &listener)
+{
+    m_mainwindow->addPreCloseListener(listener);
+}
+
 void ICore::saveSettings()
 {
     emit m_instance->saveSettingsRequested();
diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h
index f5d3ddc705f..caa13ed670a 100644
--- a/src/plugins/coreplugin/icore.h
+++ b/src/plugins/coreplugin/icore.h
@@ -37,6 +37,8 @@
 #include <QObject>
 #include <QSettings>
 
+#include <functional>
+
 QT_BEGIN_NAMESPACE
 class QPrinter;
 class QStatusBar;
@@ -132,6 +134,8 @@ public:
     };
     static void openFiles(const QStringList &fileNames, OpenFilesFlags flags = None);
 
+    static void addPreCloseListener(const std::function<bool()> &listener);
+
 public slots:
     static void saveSettings();
 
diff --git a/src/plugins/coreplugin/icorelistener.cpp b/src/plugins/coreplugin/icorelistener.cpp
deleted file mode 100644
index 6fc5e9e6249..00000000000
--- a/src/plugins/coreplugin/icorelistener.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "icorelistener.h"
-
-/*!
-    \class Core::ICoreListener
-
-    \brief The ICoreListener class provides a hook for plugins to veto on
-    certain events emitted from the core plugin.
-
-    Implement this interface to prevent certain events from occurring. For
-    example, to prevent the closing of the whole application
-    or to prevent the closing of an editor window under certain conditions.
-
-    For example, if the application window requests a close,
-    \c ICoreListener::coreAboutToClose() is called (in arbitrary order) on all
-    registered objects implementing this interface. If one if these calls
-    returns \c false, the process is aborted and the event is ignored.  If all
-    calls return \c true, the corresponding signal is emitted and the event is
-    accepted or performed.
-
-    Guidelines for implementing the class:
-    \list
-        \li Return \c false from the implemented function if you want to prevent
-            the event.
-        \li Add your implementing object to the plugin managers objects:
-            \c{ExtensionSystem::PluginManager::instance()->addObject(yourImplementingObject)}
-        \li Do not forget to remove the object again at deconstruction
-            (for example, in the destructor of your plugin).
-    \endlist
-*/
diff --git a/src/plugins/coreplugin/icorelistener.h b/src/plugins/coreplugin/icorelistener.h
deleted file mode 100644
index d3debac5a09..00000000000
--- a/src/plugins/coreplugin/icorelistener.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#ifndef ICORELISTENER_H
-#define ICORELISTENER_H
-
-#include "core_global.h"
-#include <QObject>
-
-namespace Core {
-class IEditor;
-
-class CORE_EXPORT ICoreListener : public QObject
-{
-    Q_OBJECT
-public:
-    ICoreListener(QObject *parent = 0) : QObject(parent) {}
-    virtual ~ICoreListener() {}
-
-    virtual bool editorAboutToClose(IEditor * /*editor*/) { return true; }
-    virtual bool coreAboutToClose() { return true; }
-};
-
-} // namespace Core
-
-#endif // ICORELISTENER_H
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index c20b7259b3d..f1adda1e431 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -69,7 +69,6 @@
 #include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/editormanager_p.h>
 #include <coreplugin/editormanager/ieditor.h>
-#include <coreplugin/icorelistener.h>
 #include <coreplugin/inavigationwidgetfactory.h>
 #include <coreplugin/progressmanager/progressmanager_p.h>
 #include <coreplugin/progressmanager/progressview.h>
@@ -250,6 +249,11 @@ void MainWindow::appendAboutInformation(const QString &line)
     m_aboutInformation.append(line);
 }
 
+void MainWindow::addPreCloseListener(const std::function<bool ()> &listener)
+{
+    m_preCloseListeners.append(listener);
+}
+
 MainWindow::~MainWindow()
 {
     // explicitly delete window support, because that calls methods from ICore that call methods
@@ -370,10 +374,8 @@ void MainWindow::closeEvent(QCloseEvent *event)
         return;
     }
 
-    const QList<ICoreListener *> listeners =
-        PluginManager::getObjects<ICoreListener>();
-    foreach (ICoreListener *listener, listeners) {
-        if (!listener->coreAboutToClose()) {
+    foreach (const std::function<bool()> &listener, m_preCloseListeners) {
+        if (!listener()) {
             event->ignore();
             return;
         }
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 6db2c82c504..c6791177a16 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -40,6 +40,8 @@
 #include <QMap>
 #include <QColor>
 
+#include <functional>
+
 QT_BEGIN_NAMESPACE
 class QSettings;
 class QPrinter;
@@ -113,6 +115,8 @@ public:
     QStringList additionalAboutInformation() const;
     void appendAboutInformation(const QString &line);
 
+    void addPreCloseListener(const std::function<bool()> &listener);
+
 signals:
     void newItemDialogRunningChanged();
 
@@ -201,6 +205,7 @@ private:
 
     QToolButton *m_toggleSideBarButton;
     QColor m_overrideColor;
+    QList<std::function<bool()>> m_preCloseListeners;
 };
 
 } // namespace Internal
diff --git a/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.cpp b/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.cpp
deleted file mode 100644
index 51035427920..00000000000
--- a/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "corelistenercheckingforrunningbuild.h"
-#include "projectexplorer.h"
-
-namespace ProjectExplorer {
-namespace Internal {
-
-CoreListener::CoreListener()
-{
-}
-
-bool CoreListener::coreAboutToClose()
-{
-    return ProjectExplorerPlugin::coreAboutToClose();
-}
-
-}
-}
diff --git a/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.h b/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.h
deleted file mode 100644
index e28b3ff1da8..00000000000
--- a/src/plugins/projectexplorer/corelistenercheckingforrunningbuild.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#ifndef CORELISTENERCHECKINGFORRUNNINGBUILD_H
-#define CORELISTENERCHECKINGFORRUNNINGBUILD_H
-
-#include <coreplugin/icorelistener.h>
-
-namespace ProjectExplorer {
-
-namespace Internal {
-
-class CoreListener : public Core::ICoreListener
-{
-    Q_OBJECT
-public:
-    CoreListener();
-
-    bool coreAboutToClose();
-};
-
-} // namespace Internal
-} // namespace ProjectExplorer
-
-#endif // CORELISTENERCHECKINGFORRUNNINGBUILD_H
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 3e8945cc119..7eff58056ef 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -79,7 +79,6 @@
 #include "projectnodes.h"
 #include "sessiondialog.h"
 #include "projectexplorersettingspage.h"
-#include "corelistenercheckingforrunningbuild.h"
 #include "buildconfiguration.h"
 #include "miniprojecttargetselector.h"
 #include "taskhub.h"
@@ -559,7 +558,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
     addAutoReleasedObject(new RemoveTaskHandler);
     addAutoReleasedObject(new ConfigTaskHandler(Task::compilerMissingTask(),
                                                 Constants::KITS_SETTINGS_PAGE_ID));
-    addAutoReleasedObject(new CoreListener);
+
+    ICore::addPreCloseListener([]() -> bool { return coreAboutToClose(); });
 
     dd->m_outputPane = new AppOutputPane;
     addAutoReleasedObject(dd->m_outputPane);
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 8cf7433d9ac..255e7883256 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -135,7 +135,6 @@ public:
     // internal public for FlatModel
     static void renameFile(Node *node, const QString &newFilePath);
     static QStringList projectFilePatterns();
-    static bool coreAboutToClose();
     static QList<QPair<QString, QString> > recentProjects();
 
     static bool canRun(Project *pro, Core::Id runMode, QString *whyNot = 0);
@@ -160,6 +159,9 @@ public:
 
     static void updateContextMenuActions();
 
+private:
+    static bool coreAboutToClose();
+
 signals:
     void runControlStarted(ProjectExplorer::RunControl *rc);
     void runControlFinished(ProjectExplorer::RunControl *rc);
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 9ce399bbb7f..9f776e67978 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -59,7 +59,6 @@ HEADERS += projectexplorer.h \
     gnumakeparser.h \
     projectexplorerconstants.h \
     projectexplorersettings.h \
-    corelistenercheckingforrunningbuild.h \
     project.h \
     iprojectmanager.h \
     currentprojectfilter.h \
@@ -238,7 +237,6 @@ SOURCES += projectexplorer.cpp \
     cesdkhandler.cpp \
     gccparser.cpp \
     projectexplorersettingspage.cpp \
-    corelistenercheckingforrunningbuild.cpp \
     baseprojectwizarddialog.cpp \
     miniprojecttargetselector.cpp \
     targetselector.cpp \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 863a39b0533..c64178865ea 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -47,7 +47,6 @@ QtcPlugin {
             "compileoutputwindow.cpp", "compileoutputwindow.h",
             "configtaskhandler.cpp", "configtaskhandler.h",
             "copytaskhandler.cpp", "copytaskhandler.h",
-            "corelistenercheckingforrunningbuild.cpp", "corelistenercheckingforrunningbuild.h",
             "currentprojectfilter.cpp", "currentprojectfilter.h",
             "currentprojectfind.cpp", "currentprojectfind.h",
             "customparser.cpp", "customparser.h",
diff --git a/src/plugins/vcsbase/corelistener.cpp b/src/plugins/vcsbase/corelistener.cpp
deleted file mode 100644
index 408fe71df9e..00000000000
--- a/src/plugins/vcsbase/corelistener.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "corelistener.h"
-#include "vcsbasesubmiteditor.h"
-
-/*!
-    \class VcsBase::Internal::CoreListener
-
-    \brief The CoreListener class catches the closing of a submit editor.
-
-    Catches the closing of a submit editor to trigger the submit.
-    One instance of this class exists, connected to the instances
-    of VcsBasePlugin, which dispatch if the editor kind matches theirs
-    (which is why the approach of passing the bool result was chosen).
-*/
-
-namespace VcsBase {
-namespace Internal {
-
-CoreListener::CoreListener(QObject *parent) :
-    ICoreListener(parent)
-{
-}
-
-bool CoreListener::editorAboutToClose(Core::IEditor *editor)
-{
-    bool result = true;
-    if (editor)
-        if (VcsBase::VcsBaseSubmitEditor *se = qobject_cast<VcsBase::VcsBaseSubmitEditor *>(editor))
-            emit submitEditorAboutToClose(se, &result);
-    return result;
-}
-
-} // namespace Internal
-} // namespace VcsBase
diff --git a/src/plugins/vcsbase/corelistener.h b/src/plugins/vcsbase/corelistener.h
deleted file mode 100644
index 1c385e2f0cb..00000000000
--- a/src/plugins/vcsbase/corelistener.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company.  For licensing terms and
-** conditions see http://www.qt.io/terms-conditions.  For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights.  These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#ifndef CORELISTENER_H
-#define CORELISTENER_H
-
-#include <coreplugin/icorelistener.h>
-
-namespace VcsBase {
-
-class VcsBaseSubmitEditor;
-
-namespace Internal {
-
-class CoreListener : public Core::ICoreListener
-{
-    Q_OBJECT
-
-public:
-    explicit CoreListener(QObject *parent = 0);
-    bool editorAboutToClose(Core::IEditor *editor);
-
-signals:
-    void submitEditorAboutToClose(VcsBaseSubmitEditor *e, bool *result);
-};
-
-} // namespace Internal
-} // namespace VcsBase
-
-#endif // CORELISTENER_H
diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro
index b433f817433..a6364aa22f0 100644
--- a/src/plugins/vcsbase/vcsbase.pro
+++ b/src/plugins/vcsbase/vcsbase.pro
@@ -7,7 +7,6 @@ HEADERS += vcsbase_global.h \
     wizard/vcscommandpage.h \
     wizard/vcsjsextension.h \
     vcsplugin.h \
-    corelistener.h \
     vcsbaseplugin.h \
     baseannotationhighlighter.h \
     diffandloghighlighter.h \
@@ -36,7 +35,6 @@ SOURCES += vcsplugin.cpp \
     wizard/vcsconfigurationpage.cpp \
     wizard/vcscommandpage.cpp \
     wizard/vcsjsextension.cpp \
-    corelistener.cpp \
     baseannotationhighlighter.cpp \
     diffandloghighlighter.cpp \
     vcsbaseeditor.cpp \
diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs
index 857577a46a9..df2ca5b878a 100644
--- a/src/plugins/vcsbase/vcsbase.qbs
+++ b/src/plugins/vcsbase/vcsbase.qbs
@@ -32,8 +32,6 @@ QtcPlugin {
         "commonsettingspage.ui",
         "commonvcssettings.cpp",
         "commonvcssettings.h",
-        "corelistener.cpp",
-        "corelistener.h",
         "diffandloghighlighter.cpp",
         "diffandloghighlighter.h",
         "nicknamedialog.cpp",
diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp
index fcd2ed42c82..cf94ea9b06a 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.cpp
+++ b/src/plugins/vcsbase/vcsbaseplugin.cpp
@@ -33,7 +33,6 @@
 #include "vcsplugin.h"
 #include "commonvcssettings.h"
 #include "vcsoutputwindow.h"
-#include "corelistener.h"
 #include "vcscommand.h"
 
 #include <coreplugin/documentmanager.h>
@@ -567,7 +566,7 @@ void VcsBasePlugin::initializeVcs(IVersionControl *vc, const Context &context)
     addAutoReleasedObject(vc);
 
     Internal::VcsPlugin *plugin = Internal::VcsPlugin::instance();
-    connect(plugin->coreListener(), &Internal::CoreListener::submitEditorAboutToClose,
+    connect(plugin, &Internal::VcsPlugin::submitEditorAboutToClose,
             this, &VcsBasePlugin::slotSubmitEditorAboutToClose);
     // First time: create new listener
     if (!VcsBasePluginPrivate::m_listener)
diff --git a/src/plugins/vcsbase/vcsplugin.cpp b/src/plugins/vcsbase/vcsplugin.cpp
index 49037559cbf..04af5ca0069 100644
--- a/src/plugins/vcsbase/vcsplugin.cpp
+++ b/src/plugins/vcsbase/vcsplugin.cpp
@@ -31,16 +31,18 @@
 #include "vcsplugin.h"
 
 #include "vcsbaseconstants.h"
+#include "vcsbasesubmiteditor.h"
 
 #include "commonsettingspage.h"
 #include "nicknamedialog.h"
 #include "vcsoutputwindow.h"
 #include "vcsprojectcache.h"
-#include "corelistener.h"
 #include "wizard/vcscommandpage.h"
 #include "wizard/vcsconfigurationpage.h"
 #include "wizard/vcsjsextension.h"
 
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
 #include <coreplugin/iversioncontrol.h>
 #include <coreplugin/jsexpander.h>
 #include <coreplugin/vcsmanager.h>
@@ -64,8 +66,7 @@ VcsPlugin *VcsPlugin::m_instance = 0;
 
 VcsPlugin::VcsPlugin() :
     m_settingsPage(0),
-    m_nickNameModel(0),
-    m_coreListener(0)
+    m_nickNameModel(0)
 {
     m_instance = this;
 }
@@ -81,8 +82,12 @@ bool VcsPlugin::initialize(const QStringList &arguments, QString *errorMessage)
     Q_UNUSED(arguments)
     Q_UNUSED(errorMessage)
 
-    m_coreListener = new CoreListener;
-    addAutoReleasedObject(m_coreListener);
+    EditorManager::addCloseEditorListener([this](IEditor *editor) -> bool {
+        bool result = true;
+        if (auto se = qobject_cast<VcsBaseSubmitEditor *>(editor))
+            emit submitEditorAboutToClose(se, &result);
+        return result;
+    });
 
     m_settingsPage = new CommonOptionsPage;
     addAutoReleasedObject(m_settingsPage);
@@ -139,11 +144,6 @@ VcsPlugin *VcsPlugin::instance()
     return m_instance;
 }
 
-CoreListener *VcsPlugin::coreListener() const
-{
-    return m_coreListener;
-}
-
 CommonVcsSettings VcsPlugin::settings() const
 {
     return m_settingsPage->settings();
diff --git a/src/plugins/vcsbase/vcsplugin.h b/src/plugins/vcsbase/vcsplugin.h
index 5c9a2523f64..d0b308139ac 100644
--- a/src/plugins/vcsbase/vcsplugin.h
+++ b/src/plugins/vcsbase/vcsplugin.h
@@ -38,6 +38,9 @@ class QStandardItemModel;
 QT_END_NAMESPACE
 
 namespace VcsBase {
+
+class VcsBaseSubmitEditor;
+
 namespace Internal {
 
 class CommonVcsSettings;
@@ -59,8 +62,6 @@ public:
 
     static VcsPlugin *instance();
 
-    CoreListener *coreListener() const;
-
     CommonVcsSettings settings() const;
 
     // Model of user nick names used for the submit
@@ -70,6 +71,7 @@ public:
 
 signals:
     void settingsChanged(const VcsBase::Internal::CommonVcsSettings &s);
+    void submitEditorAboutToClose(VcsBase::VcsBaseSubmitEditor *e, bool *result);
 
 private slots:
     void slotSettingsChanged();
@@ -80,7 +82,6 @@ private:
     static VcsPlugin *m_instance;
     CommonOptionsPage *m_settingsPage;
     QStandardItemModel *m_nickNameModel;
-    CoreListener *m_coreListener;
 };
 
 } // namespace Internal
-- 
GitLab