forked from qt-creator/qt-creator
Provide "Restart Now" functionality
And use it for the plugin dialog and when changing the UI language. Change-Id: Ic767837d2526409f7ec46d7e4612a1499f19459e Reviewed-by: hjk <hjk@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
#include <qtsingleapplication.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
@@ -56,6 +57,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
@@ -356,6 +358,9 @@ struct Options
|
||||
QString settingsPath;
|
||||
QString installSettingsPath;
|
||||
QStringList customPluginPaths;
|
||||
// list of arguments that were handled and not passed to the application or plugin manager
|
||||
QStringList preAppArguments;
|
||||
// list of arguments to be passed to the application or plugin manager
|
||||
std::vector<char *> appArguments;
|
||||
Utils::optional<QString> userLibraryPath;
|
||||
bool hasTestOption = false;
|
||||
@@ -375,17 +380,22 @@ Options parseCommandLine(int argc, char *argv[])
|
||||
if (arg == SETTINGS_OPTION && hasNext) {
|
||||
++it;
|
||||
options.settingsPath = QDir::fromNativeSeparators(nextArg);
|
||||
options.preAppArguments << arg << nextArg;
|
||||
} else if (arg == INSTALL_SETTINGS_OPTION && hasNext) {
|
||||
++it;
|
||||
options.installSettingsPath = QDir::fromNativeSeparators(nextArg);
|
||||
options.preAppArguments << arg << nextArg;
|
||||
} else if (arg == PLUGINPATH_OPTION && hasNext) {
|
||||
++it;
|
||||
options.customPluginPaths += QDir::fromNativeSeparators(nextArg);
|
||||
options.preAppArguments << arg << nextArg;
|
||||
} else if (arg == USER_LIBRARY_PATH_OPTION && hasNext) {
|
||||
++it;
|
||||
options.userLibraryPath = nextArg;
|
||||
options.preAppArguments << arg << nextArg;
|
||||
} else if (arg == TEMPORARY_CLEAN_SETTINGS1 || arg == TEMPORARY_CLEAN_SETTINGS2) {
|
||||
options.wantsCleanSettings = true;
|
||||
options.preAppArguments << arg;
|
||||
} else { // arguments that are still passed on to the application
|
||||
if (arg == TEST_OPTION)
|
||||
options.hasTestOption = true;
|
||||
@@ -396,8 +406,49 @@ Options parseCommandLine(int argc, char *argv[])
|
||||
return options;
|
||||
}
|
||||
|
||||
class Restarter
|
||||
{
|
||||
public:
|
||||
Restarter(int argc, char *argv[])
|
||||
{
|
||||
Q_UNUSED(argc)
|
||||
m_executable = QString::fromLocal8Bit(argv[0]);
|
||||
m_workingPath = QDir::currentPath();
|
||||
}
|
||||
|
||||
void setArguments(const QStringList &args) { m_args = args; }
|
||||
|
||||
QStringList arguments() const { return m_args; }
|
||||
|
||||
int restartOrExit(int exitCode)
|
||||
{
|
||||
return qApp->property("restart").toBool() ? restart(exitCode) : exitCode;
|
||||
}
|
||||
|
||||
int restart(int exitCode)
|
||||
{
|
||||
QProcess::startDetached(m_executable, m_args, m_workingPath);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_executable;
|
||||
QStringList m_args;
|
||||
QString m_workingPath;
|
||||
};
|
||||
|
||||
QStringList lastSessionArgument()
|
||||
{
|
||||
// using insider information here is not particularly beautiful, anyhow
|
||||
const bool hasProjectExplorer = Utils::anyOf(PluginManager::plugins(),
|
||||
Utils::equal(&PluginSpec::name,
|
||||
QString("ProjectExplorer")));
|
||||
return hasProjectExplorer ? QStringList({"-lastsession"}) : QStringList();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Restarter restarter(argc, argv);
|
||||
Utils::Environment::systemEnvironment(); // cache system environment before we do any changes
|
||||
|
||||
// Manually determine various command line options
|
||||
@@ -553,6 +604,8 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
restarter.setArguments(options.preAppArguments + PluginManager::argumentsForRestart()
|
||||
+ lastSessionArgument());
|
||||
|
||||
const PluginSpecSet plugins = PluginManager::plugins();
|
||||
PluginSpec *coreplugin = nullptr;
|
||||
@@ -638,5 +691,5 @@ int main(int argc, char **argv)
|
||||
// shutdown plugin manager on the exit
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown);
|
||||
|
||||
return app.exec();
|
||||
return restarter.restartOrExit(app.exec());
|
||||
}
|
||||
|
@@ -63,6 +63,7 @@ OptionsParser::OptionsParser(const QStringList &args,
|
||||
if (m_foundAppOptions)
|
||||
m_foundAppOptions->clear();
|
||||
m_pmPrivate->arguments.clear();
|
||||
m_pmPrivate->argumentsForRestart.clear();
|
||||
}
|
||||
|
||||
bool OptionsParser::parse()
|
||||
@@ -185,6 +186,7 @@ bool OptionsParser::checkForLoadOption()
|
||||
m_isDependencyRefreshNeeded = true;
|
||||
}
|
||||
}
|
||||
m_pmPrivate->argumentsForRestart << QLatin1String(LOAD_OPTION) << m_currentArg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -213,6 +215,7 @@ bool OptionsParser::checkForNoLoadOption()
|
||||
m_isDependencyRefreshNeeded = true;
|
||||
}
|
||||
}
|
||||
m_pmPrivate->argumentsForRestart << QLatin1String(NO_LOAD_OPTION) << m_currentArg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -247,8 +250,11 @@ bool OptionsParser::checkForPluginOption()
|
||||
if (!spec)
|
||||
return false;
|
||||
spec->addArgument(m_currentArg);
|
||||
if (requiresParameter && nextToken(RequiredToken))
|
||||
m_pmPrivate->argumentsForRestart << m_currentArg;
|
||||
if (requiresParameter && nextToken(RequiredToken)) {
|
||||
spec->addArgument(m_currentArg);
|
||||
m_pmPrivate->argumentsForRestart << m_currentArg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -536,6 +536,17 @@ QStringList PluginManager::arguments()
|
||||
return d->arguments;
|
||||
}
|
||||
|
||||
/*!
|
||||
The arguments that should be used when automatically restarting the application.
|
||||
This includes plugin manager related options for enabling or disabling plugins,
|
||||
but excludes others, like the arguments returned by arguments() and the appOptions
|
||||
passed to the parseOptions() method.
|
||||
*/
|
||||
QStringList PluginManager::argumentsForRestart()
|
||||
{
|
||||
return d->argumentsForRestart;
|
||||
}
|
||||
|
||||
/*!
|
||||
List of all plugin specifications that have been found in the plugin search paths.
|
||||
This list is valid directly after the setPluginPaths() call.
|
||||
|
@@ -106,6 +106,7 @@ public:
|
||||
|
||||
// command line arguments
|
||||
static QStringList arguments();
|
||||
static QStringList argumentsForRestart();
|
||||
static bool parseOptions(const QStringList &args,
|
||||
const QMap<QString, bool> &appOptions,
|
||||
QMap<QString, QString> *foundAppOptions,
|
||||
|
@@ -118,6 +118,7 @@ public:
|
||||
QEventLoop *shutdownEventLoop = nullptr; // used for async shutdown
|
||||
|
||||
QStringList arguments;
|
||||
QStringList argumentsForRestart;
|
||||
QScopedPointer<QElapsedTimer> m_profileTimer;
|
||||
QHash<const PluginSpec *, int> m_profileTotal;
|
||||
int m_profileElapsedMS = 0;
|
||||
|
@@ -25,6 +25,7 @@ add_qtc_plugin(Core
|
||||
dialogs/openwithdialog.cpp dialogs/openwithdialog.h dialogs/openwithdialog.ui
|
||||
dialogs/promptoverwritedialog.cpp dialogs/promptoverwritedialog.h
|
||||
dialogs/readonlyfilesdialog.cpp dialogs/readonlyfilesdialog.h dialogs/readonlyfilesdialog.ui
|
||||
dialogs/restartdialog.cpp dialogs/restartdialog.h
|
||||
dialogs/saveitemsdialog.cpp dialogs/saveitemsdialog.h dialogs/saveitemsdialog.ui
|
||||
dialogs/settingsdialog.cpp dialogs/settingsdialog.h
|
||||
dialogs/shortcutsettings.cpp dialogs/shortcutsettings.h
|
||||
|
@@ -101,6 +101,7 @@ SOURCES += corejsextensions.cpp \
|
||||
documentmanager.cpp \
|
||||
iversioncontrol.cpp \
|
||||
dialogs/addtovcsdialog.cpp \
|
||||
dialogs/restartdialog.cpp \
|
||||
ioutputpane.cpp \
|
||||
patchtool.cpp \
|
||||
windowsupport.cpp \
|
||||
@@ -216,6 +217,7 @@ HEADERS += corejsextensions.h \
|
||||
textdocument.h \
|
||||
documentmanager.h \
|
||||
dialogs/addtovcsdialog.h \
|
||||
dialogs/restartdialog.h \
|
||||
patchtool.h \
|
||||
windowsupport.h \
|
||||
opendocumentstreeview.h \
|
||||
|
@@ -216,6 +216,7 @@ Project {
|
||||
"openwithdialog.cpp", "openwithdialog.h", "openwithdialog.ui",
|
||||
"promptoverwritedialog.cpp", "promptoverwritedialog.h",
|
||||
"readonlyfilesdialog.cpp", "readonlyfilesdialog.h", "readonlyfilesdialog.ui",
|
||||
"restartdialog.cpp", "restartdialog.h",
|
||||
"saveitemsdialog.cpp", "saveitemsdialog.h", "saveitemsdialog.ui",
|
||||
"settingsdialog.cpp", "settingsdialog.h",
|
||||
"shortcutsettings.cpp", "shortcutsettings.h",
|
||||
|
49
src/plugins/coreplugin/dialogs/restartdialog.cpp
Normal file
49
src/plugins/coreplugin/dialogs/restartdialog.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "restartdialog.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
||||
namespace Core {
|
||||
|
||||
RestartDialog::RestartDialog(QWidget *parent, const QString &text)
|
||||
: QMessageBox(parent)
|
||||
{
|
||||
setWindowTitle(tr("Restart Required"));
|
||||
setText(text);
|
||||
setIcon(QMessageBox::Information);
|
||||
addButton(tr("Later"), QMessageBox::NoRole);
|
||||
addButton(tr("Restart Now"), QMessageBox::YesRole);
|
||||
|
||||
connect(this, &QDialog::accepted, this, [] {
|
||||
QTimer::singleShot(0, ICore::instance(), [] { ICore::restart(); });
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Core
|
40
src/plugins/coreplugin/dialogs/restartdialog.h
Normal file
40
src/plugins/coreplugin/dialogs/restartdialog.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CORE_EXPORT RestartDialog : public QMessageBox
|
||||
{
|
||||
public:
|
||||
RestartDialog(QWidget *parent, const QString &text);
|
||||
};
|
||||
|
||||
} // namespace Core
|
@@ -28,6 +28,8 @@
|
||||
#include "icore.h"
|
||||
#include "infobar.h"
|
||||
|
||||
#include <coreplugin/dialogs/restartdialog.h>
|
||||
|
||||
#include <utils/checkablemessagebox.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/stylehelper.h>
|
||||
@@ -199,9 +201,11 @@ QString GeneralSettings::language() const
|
||||
void GeneralSettings::setLanguage(const QString &locale)
|
||||
{
|
||||
QSettings *settings = ICore::settings();
|
||||
if (settings->value(QLatin1String("General/OverrideLanguage")).toString() != locale)
|
||||
QMessageBox::information(ICore::mainWindow(), tr("Restart Required"),
|
||||
tr("The language change will take effect after restart."));
|
||||
if (settings->value(QLatin1String("General/OverrideLanguage")).toString() != locale) {
|
||||
RestartDialog dialog(ICore::dialogParent(),
|
||||
tr("The language change will take effect after restart."));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
if (locale.isEmpty())
|
||||
settings->remove(QLatin1String("General/OverrideLanguage"));
|
||||
|
@@ -710,6 +710,11 @@ void ICore::setupScreenShooter(const QString &name, QWidget *w, const QRect &rc)
|
||||
new ScreenShooter(w, name, rc);
|
||||
}
|
||||
|
||||
void ICore::restart()
|
||||
{
|
||||
m_mainwindow->restart();
|
||||
}
|
||||
|
||||
void ICore::saveSettings(SaveSettingsReason reason)
|
||||
{
|
||||
emit m_instance->saveSettingsRequested(reason);
|
||||
|
@@ -153,6 +153,8 @@ public:
|
||||
MainWindowClosing,
|
||||
};
|
||||
|
||||
static void restart();
|
||||
|
||||
public slots:
|
||||
static void saveSettings(SaveSettingsReason reason);
|
||||
|
||||
|
@@ -329,8 +329,24 @@ void MainWindow::extensionsInitialized()
|
||||
QTimer::singleShot(0, m_coreImpl, &ICore::coreOpened);
|
||||
}
|
||||
|
||||
static void setRestart(bool restart)
|
||||
{
|
||||
qApp->setProperty("restart", restart);
|
||||
}
|
||||
|
||||
void MainWindow::restart()
|
||||
{
|
||||
setRestart(true);
|
||||
exit();
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
const auto cancelClose = [event] {
|
||||
event->ignore();
|
||||
setRestart(false);
|
||||
};
|
||||
|
||||
// work around QTBUG-43344
|
||||
static bool alreadyClosed = false;
|
||||
if (alreadyClosed) {
|
||||
@@ -342,13 +358,13 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
|
||||
// Save opened files
|
||||
if (!DocumentManager::saveAllModifiedDocuments()) {
|
||||
event->ignore();
|
||||
cancelClose();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (const std::function<bool()> &listener, m_preCloseListeners) {
|
||||
if (!listener()) {
|
||||
event->ignore();
|
||||
cancelClose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -108,6 +108,8 @@ public:
|
||||
|
||||
void saveSettings();
|
||||
|
||||
void restart();
|
||||
|
||||
public slots:
|
||||
void openFileWith();
|
||||
void exit();
|
||||
|
@@ -25,6 +25,10 @@
|
||||
|
||||
#include "plugindialog.h"
|
||||
|
||||
#include "icore.h"
|
||||
|
||||
#include "dialogs/restartdialog.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginview.h>
|
||||
#include <extensionsystem/plugindetailsview.h>
|
||||
@@ -116,6 +120,11 @@ PluginDialog::PluginDialog(QWidget *parent)
|
||||
void PluginDialog::closeDialog()
|
||||
{
|
||||
ExtensionSystem::PluginManager::writeSettings();
|
||||
if (s_isRestartRequired) {
|
||||
RestartDialog restartDialog(ICore::dialogParent(),
|
||||
tr("Plugin changes will take effect after restart."));
|
||||
restartDialog.exec();
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,8 @@
|
||||
#include "manhattanstyle.h"
|
||||
#include "themechooser.h"
|
||||
|
||||
#include "dialogs/restartdialog.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/theme/theme.h>
|
||||
#include <utils/theme/theme_p.h>
|
||||
@@ -178,11 +180,11 @@ void ThemeChooser::apply()
|
||||
QSettings *settings = ICore::settings();
|
||||
const QString currentThemeId = ThemeEntry::themeSetting().toString();
|
||||
if (currentThemeId != themeId) {
|
||||
QMessageBox::information(ICore::mainWindow(), tr("Restart Required"),
|
||||
tr("The theme change will take effect after restart."));
|
||||
|
||||
// save filename of selected theme in global config
|
||||
settings->setValue(QLatin1String(Constants::SETTINGS_THEME), themeId);
|
||||
RestartDialog restartDialog(ICore::dialogParent(),
|
||||
tr("The theme change will take effect after restart."));
|
||||
restartDialog.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user