From 1f0ecd600e7ddf184ef248c64aad6444462950ec Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 21 Jan 2022 14:38:50 +0100 Subject: [PATCH] Move TerminalCommand into a separate file This will ease the ConsoleProcess and QtcProcess unification. Change-Id: Idda9ad393d184088c3e3a734389761d7176bd0c0 Reviewed-by: hjk --- src/app/main.cpp | 4 +- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/consoleprocess.cpp | 157 +----------------- src/libs/utils/consoleprocess.h | 27 ---- src/libs/utils/terminalcommand.cpp | 186 ++++++++++++++++++++++ src/libs/utils/terminalcommand.h | 65 ++++++++ src/libs/utils/utils.qbs | 2 + src/plugins/coreplugin/systemsettings.cpp | 7 +- 8 files changed, 263 insertions(+), 186 deletions(-) create mode 100644 src/libs/utils/terminalcommand.cpp create mode 100644 src/libs/utils/terminalcommand.h diff --git a/src/app/main.cpp b/src/app/main.cpp index 381ab9229ff..d9e91f21d17 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include #include @@ -552,7 +552,7 @@ int main(int argc, char **argv) QSettings::SystemScope, QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), QLatin1String(Core::Constants::IDE_CASED_ID)); - Utils::ConsoleProcess::setSettings(settings); + Utils::TerminalCommand::setSettings(settings); loadFonts(); if (Utils::HostOsInfo::isWindowsHost() diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 0f7d4273cc7..d3f0f01c685 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -164,6 +164,7 @@ add_qtc_library(Utils templateengine.cpp templateengine.h temporarydirectory.cpp temporarydirectory.h temporaryfile.cpp temporaryfile.h + terminalcommand.cpp terminalcommand.h textfieldcheckbox.cpp textfieldcheckbox.h textfieldcombobox.cpp textfieldcombobox.h textfileformat.cpp textfileformat.h diff --git a/src/libs/utils/consoleprocess.cpp b/src/libs/utils/consoleprocess.cpp index a21af468d30..6db9da5dfd3 100644 --- a/src/libs/utils/consoleprocess.cpp +++ b/src/libs/utils/consoleprocess.cpp @@ -25,22 +25,20 @@ #include "consoleprocess.h" -#include #include #include #include #include #include +#include #include #include #include #include -#include #include #include #include -#include #include #include #include @@ -118,18 +116,6 @@ static QString msgCannotExecute(const QString & p, const QString &why) return ConsoleProcess::tr("Cannot execute \"%1\": %2").arg(p, why); } -static QSettings *s_settings = nullptr; - -// TerminalCommand - -TerminalCommand::TerminalCommand(const QString &command, const QString &openArgs, const QString &executeArgs, bool needsQuotes) - : command(command) - , openArgs(openArgs) - , executeArgs(executeArgs) - , needsQuotes(needsQuotes) -{ -} - // ConsoleProcessPrivate class ConsoleProcessPrivate @@ -196,126 +182,6 @@ const CommandLine &ConsoleProcess::commandLine() const return d->m_commandLine; } -void ConsoleProcess::setSettings(QSettings *settings) -{ - s_settings = settings; -} - -Q_GLOBAL_STATIC_WITH_ARGS(const QVector, knownTerminals, ( -{ - {"x-terminal-emulator", "", "-e"}, - {"xdg-terminal", "", "", true}, - {"xterm", "", "-e"}, - {"aterm", "", "-e"}, - {"Eterm", "", "-e"}, - {"rxvt", "", "-e"}, - {"urxvt", "", "-e"}, - {"xfce4-terminal", "", "-x"}, - {"konsole", "--separate --workdir .", "-e"}, - {"gnome-terminal", "", "--"} -})); - -TerminalCommand ConsoleProcess::defaultTerminalEmulator() -{ - static TerminalCommand defaultTerm; - - if (defaultTerm.command.isEmpty()) { - - if (HostOsInfo::isMacHost()) { - const QString termCmd = QCoreApplication::applicationDirPath() - + "/../Resources/scripts/openTerminal.py"; - if (QFileInfo::exists(termCmd)) - defaultTerm = {termCmd, "", ""}; - else - defaultTerm = {"/usr/X11/bin/xterm", "", "-e"}; - - } else if (HostOsInfo::isAnyUnixHost()) { - defaultTerm = {"xterm", "", "-e"}; - const Environment env = Environment::systemEnvironment(); - for (const TerminalCommand &term : *knownTerminals) { - const QString result = env.searchInPath(term.command).toString(); - if (!result.isEmpty()) { - defaultTerm = {result, term.openArgs, term.executeArgs, term.needsQuotes}; - break; - } - } - } - } - - return defaultTerm; -} - -QVector ConsoleProcess::availableTerminalEmulators() -{ - QVector result; - - if (HostOsInfo::isAnyUnixHost()) { - const Environment env = Environment::systemEnvironment(); - for (const TerminalCommand &term : *knownTerminals) { - const QString command = env.searchInPath(term.command).toString(); - if (!command.isEmpty()) - result.push_back({command, term.openArgs, term.executeArgs}); - } - // sort and put default terminal on top - const TerminalCommand defaultTerm = defaultTerminalEmulator(); - result.removeAll(defaultTerm); - sort(result); - result.prepend(defaultTerm); - } - - return result; -} - -const char kTerminalVersion[] = "4.8"; -const char kTerminalVersionKey[] = "General/Terminal/SettingsVersion"; -const char kTerminalCommandKey[] = "General/Terminal/Command"; -const char kTerminalOpenOptionsKey[] = "General/Terminal/OpenOptions"; -const char kTerminalExecuteOptionsKey[] = "General/Terminal/ExecuteOptions"; - -TerminalCommand ConsoleProcess::terminalEmulator() -{ - if (s_settings && HostOsInfo::isAnyUnixHost()) { - if (s_settings->value(kTerminalVersionKey).toString() == kTerminalVersion) { - if (s_settings->contains(kTerminalCommandKey)) - return {s_settings->value(kTerminalCommandKey).toString(), - s_settings->value(kTerminalOpenOptionsKey).toString(), - s_settings->value(kTerminalExecuteOptionsKey).toString()}; - } else { - // TODO remove reading of old settings some time after 4.8 - const QString value = s_settings->value("General/TerminalEmulator").toString().trimmed(); - if (!value.isEmpty()) { - // split off command and options - const QStringList splitCommand = ProcessArgs::splitArgs(value); - if (QTC_GUARD(!splitCommand.isEmpty())) { - const QString command = splitCommand.first(); - const QStringList quotedArgs = Utils::transform(splitCommand.mid(1), - &ProcessArgs::quoteArgUnix); - const QString options = quotedArgs.join(' '); - return {command, "", options}; - } - } - } - } - - return defaultTerminalEmulator(); -} - -void ConsoleProcess::setTerminalEmulator(const TerminalCommand &term) -{ - if (s_settings && HostOsInfo::isAnyUnixHost()) { - s_settings->setValue(kTerminalVersionKey, kTerminalVersion); - if (term == defaultTerminalEmulator()) { - s_settings->remove(kTerminalCommandKey); - s_settings->remove(kTerminalOpenOptionsKey); - s_settings->remove(kTerminalExecuteOptionsKey); - } else { - s_settings->setValue(kTerminalCommandKey, term.command); - s_settings->setValue(kTerminalOpenOptionsKey, term.openArgs); - s_settings->setValue(kTerminalExecuteOptionsKey, term.executeArgs); - } - } -} - static QString quoteWinCommand(const QString &program) { const QChar doubleQuote = QLatin1Char('"'); @@ -373,7 +239,6 @@ QString createWinCommandline(const QString &program, const QString &args) return programName; } - bool ConsoleProcess::startTerminalEmulator(const QString &workingDir, const Environment &env) { #ifdef Q_OS_WIN @@ -405,7 +270,7 @@ bool ConsoleProcess::startTerminalEmulator(const QString &workingDir, const Envi return success; #else - const TerminalCommand term = terminalEmulator(); + const TerminalCommand term = TerminalCommand::terminalEmulator(); QProcess process; process.setProgram(term.command); process.setArguments(ProcessArgs::splitArgs(term.openArgs)); @@ -567,7 +432,7 @@ void ConsoleProcess::start() } ProcessArgs::SplitError qerr; - const TerminalCommand terminal = terminalEmulator(); + const TerminalCommand terminal = TerminalCommand::terminalEmulator(); const ProcessArgs terminalArgs = ProcessArgs::prepareArgs(terminal.executeArgs, &qerr, HostOsInfo::hostOs(), @@ -998,20 +863,4 @@ void ConsoleProcess::emitError(QProcess::ProcessError err, const QString &errorS emit errorOccurred(err); } -bool TerminalCommand::operator==(const TerminalCommand &other) const -{ - return other.command == command && other.openArgs == openArgs - && other.executeArgs == executeArgs; -} - -bool TerminalCommand::operator<(const TerminalCommand &other) const -{ - if (command == other.command) { - if (openArgs == other.openArgs) - return executeArgs < other.executeArgs; - return openArgs < other.openArgs; - } - return command < other.command; -} - } // Utils diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h index c5427d68444..f37e5d4528b 100644 --- a/src/libs/utils/consoleprocess.h +++ b/src/libs/utils/consoleprocess.h @@ -28,11 +28,6 @@ #include "utils_global.h" #include -#include - -QT_BEGIN_NAMESPACE -class QSettings; -QT_END_NAMESPACE namespace Utils { @@ -40,21 +35,6 @@ class CommandLine; class Environment; class FilePath; -class QTCREATOR_UTILS_EXPORT TerminalCommand -{ -public: - TerminalCommand() = default; - TerminalCommand(const QString &command, const QString &openArgs, const QString &executeArgs, bool needsQuotes = false); - - bool operator==(const TerminalCommand &other) const; - bool operator<(const TerminalCommand &other) const; - - QString command; - QString openArgs; - QString executeArgs; - bool needsQuotes = false; -}; - class QTCREATOR_UTILS_EXPORT ConsoleProcess : public QObject { Q_OBJECT @@ -99,11 +79,6 @@ public: int exitCode() const; QProcess::ExitStatus exitStatus() const; - static void setSettings(QSettings *settings); - static TerminalCommand defaultTerminalEmulator(); - static QVector availableTerminalEmulators(); - static TerminalCommand terminalEmulator(); - static void setTerminalEmulator(const TerminalCommand &term); static bool startTerminalEmulator(const QString &workingDir, const Utils::Environment &env); signals: @@ -131,5 +106,3 @@ private: }; } // Utils - -Q_DECLARE_METATYPE(Utils::TerminalCommand) diff --git a/src/libs/utils/terminalcommand.cpp b/src/libs/utils/terminalcommand.cpp new file mode 100644 index 00000000000..41c0604868c --- /dev/null +++ b/src/libs/utils/terminalcommand.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 "terminalcommand.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Utils { + +static QSettings *s_settings = nullptr; + +TerminalCommand::TerminalCommand(const QString &command, const QString &openArgs, + const QString &executeArgs, bool needsQuotes) + : command(command) + , openArgs(openArgs) + , executeArgs(executeArgs) + , needsQuotes(needsQuotes) +{ +} + +bool TerminalCommand::operator==(const TerminalCommand &other) const +{ + return other.command == command && other.openArgs == openArgs + && other.executeArgs == executeArgs; +} + +bool TerminalCommand::operator<(const TerminalCommand &other) const +{ + if (command == other.command) { + if (openArgs == other.openArgs) + return executeArgs < other.executeArgs; + return openArgs < other.openArgs; + } + return command < other.command; +} + +void TerminalCommand::setSettings(QSettings *settings) +{ + s_settings = settings; +} + +Q_GLOBAL_STATIC_WITH_ARGS(const QVector, knownTerminals, ( +{ + {"x-terminal-emulator", "", "-e"}, + {"xdg-terminal", "", "", true}, + {"xterm", "", "-e"}, + {"aterm", "", "-e"}, + {"Eterm", "", "-e"}, + {"rxvt", "", "-e"}, + {"urxvt", "", "-e"}, + {"xfce4-terminal", "", "-x"}, + {"konsole", "--separate --workdir .", "-e"}, + {"gnome-terminal", "", "--"} +})); + +TerminalCommand TerminalCommand::defaultTerminalEmulator() +{ + static TerminalCommand defaultTerm; + + if (defaultTerm.command.isEmpty()) { + if (HostOsInfo::isMacHost()) { + const QString termCmd = QCoreApplication::applicationDirPath() + + "/../Resources/scripts/openTerminal.py"; + if (QFileInfo::exists(termCmd)) + defaultTerm = {termCmd, "", ""}; + else + defaultTerm = {"/usr/X11/bin/xterm", "", "-e"}; + + } else if (HostOsInfo::isAnyUnixHost()) { + defaultTerm = {"xterm", "", "-e"}; + const Environment env = Environment::systemEnvironment(); + for (const TerminalCommand &term : *knownTerminals) { + const QString result = env.searchInPath(term.command).toString(); + if (!result.isEmpty()) { + defaultTerm = {result, term.openArgs, term.executeArgs, term.needsQuotes}; + break; + } + } + } + } + + return defaultTerm; +} + +QVector TerminalCommand::availableTerminalEmulators() +{ + QVector result; + + if (HostOsInfo::isAnyUnixHost()) { + const Environment env = Environment::systemEnvironment(); + for (const TerminalCommand &term : *knownTerminals) { + const QString command = env.searchInPath(term.command).toString(); + if (!command.isEmpty()) + result.push_back({command, term.openArgs, term.executeArgs}); + } + // sort and put default terminal on top + const TerminalCommand defaultTerm = defaultTerminalEmulator(); + result.removeAll(defaultTerm); + sort(result); + result.prepend(defaultTerm); + } + + return result; +} + +const char kTerminalVersion[] = "4.8"; +const char kTerminalVersionKey[] = "General/Terminal/SettingsVersion"; +const char kTerminalCommandKey[] = "General/Terminal/Command"; +const char kTerminalOpenOptionsKey[] = "General/Terminal/OpenOptions"; +const char kTerminalExecuteOptionsKey[] = "General/Terminal/ExecuteOptions"; + +TerminalCommand TerminalCommand::terminalEmulator() +{ + if (s_settings && HostOsInfo::isAnyUnixHost()) { + if (s_settings->value(kTerminalVersionKey).toString() == kTerminalVersion) { + if (s_settings->contains(kTerminalCommandKey)) + return {s_settings->value(kTerminalCommandKey).toString(), + s_settings->value(kTerminalOpenOptionsKey).toString(), + s_settings->value(kTerminalExecuteOptionsKey).toString()}; + } else { + // TODO remove reading of old settings some time after 4.8 + const QString value = s_settings->value("General/TerminalEmulator").toString().trimmed(); + if (!value.isEmpty()) { + // split off command and options + const QStringList splitCommand = ProcessArgs::splitArgs(value); + if (QTC_GUARD(!splitCommand.isEmpty())) { + const QString command = splitCommand.first(); + const QStringList quotedArgs = Utils::transform(splitCommand.mid(1), + &ProcessArgs::quoteArgUnix); + const QString options = quotedArgs.join(' '); + return {command, "", options}; + } + } + } + } + + return defaultTerminalEmulator(); +} + +void TerminalCommand::setTerminalEmulator(const TerminalCommand &term) +{ + if (s_settings && HostOsInfo::isAnyUnixHost()) { + s_settings->setValue(kTerminalVersionKey, kTerminalVersion); + if (term == defaultTerminalEmulator()) { + s_settings->remove(kTerminalCommandKey); + s_settings->remove(kTerminalOpenOptionsKey); + s_settings->remove(kTerminalExecuteOptionsKey); + } else { + s_settings->setValue(kTerminalCommandKey, term.command); + s_settings->setValue(kTerminalOpenOptionsKey, term.openArgs); + s_settings->setValue(kTerminalExecuteOptionsKey, term.executeArgs); + } + } +} + +} // Utils diff --git a/src/libs/utils/terminalcommand.h b/src/libs/utils/terminalcommand.h new file mode 100644 index 00000000000..74ec65185f7 --- /dev/null +++ b/src/libs/utils/terminalcommand.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2022 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 "utils_global.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace Utils { + +class Environment; + +class QTCREATOR_UTILS_EXPORT TerminalCommand +{ +public: + TerminalCommand() = default; + TerminalCommand(const QString &command, const QString &openArgs, + const QString &executeArgs, bool needsQuotes = false); + + bool operator==(const TerminalCommand &other) const; + bool operator<(const TerminalCommand &other) const; + + QString command; + QString openArgs; + QString executeArgs; + bool needsQuotes = false; + + static void setSettings(QSettings *settings); + static TerminalCommand defaultTerminalEmulator(); + static QVector availableTerminalEmulators(); + static TerminalCommand terminalEmulator(); + static void setTerminalEmulator(const TerminalCommand &term); +}; + +} // Utils + +Q_DECLARE_METATYPE(Utils::TerminalCommand) diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 459203234b9..8bca0897e0c 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -292,6 +292,8 @@ Project { "temporarydirectory.h", "temporaryfile.cpp", "temporaryfile.h", + "terminalcommand.cpp" + "terminalcommand.h" "textfieldcheckbox.cpp", "textfieldcheckbox.h", "textfieldcombobox.cpp", diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp index 17b10b5c5c1..77809595590 100644 --- a/src/plugins/coreplugin/systemsettings.cpp +++ b/src/plugins/coreplugin/systemsettings.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -90,10 +91,10 @@ public: m_ui.reloadBehavior->setCurrentIndex(EditorManager::reloadSetting()); if (HostOsInfo::isAnyUnixHost()) { - const QVector availableTerminals = ConsoleProcess::availableTerminalEmulators(); + const QVector availableTerminals = TerminalCommand::availableTerminalEmulators(); for (const TerminalCommand &term : availableTerminals) m_ui.terminalComboBox->addItem(term.command, QVariant::fromValue(term)); - updateTerminalUi(ConsoleProcess::terminalEmulator()); + updateTerminalUi(TerminalCommand::terminalEmulator()); connect(m_ui.terminalComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, @@ -265,7 +266,7 @@ void SystemSettingsWidget::apply() QtcSettings *settings = ICore::settings(); EditorManager::setReloadSetting(IDocument::ReloadSetting(m_ui.reloadBehavior->currentIndex())); if (HostOsInfo::isAnyUnixHost()) { - ConsoleProcess::setTerminalEmulator({m_ui.terminalComboBox->lineEdit()->text(), + TerminalCommand::setTerminalEmulator({m_ui.terminalComboBox->lineEdit()->text(), m_ui.terminalOpenArgs->text(), m_ui.terminalExecuteArgs->text()}); if (!HostOsInfo::isMacHost()) {