Commit e6a98f36 authored by hjk's avatar hjk

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: default avatarEike Ziller <eike.ziller@theqtcompany.com>
parent ed25b429
......@@ -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 \
......
......@@ -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",
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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();
......
......@@ -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
......
......@@ -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();
......
......@@ -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();
......
/****************************************************************************
**
** 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
*/
/****************************************************************************
**
** 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
......@@ -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;
}
......
......@@ -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
......
/****************************************************************************
**
** 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();
}
}
}
/****************************************************************************
**
** 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
......@@ -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);
......
......@@ -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);
......
......@@ -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 \
......
......@@ -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",
......
/****************************************************************************
**
** 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"
/*!
</