Files
qt-creator/src/libs/utils/terminalcommand.cpp
Eike Ziller b6c452d59d Terminal: Clean up settings
Qt Creator <= 10 accidentally wrote the default terminal into the
settings on macOS instead of leaving the values empty. So the change
from "openTerminal.py" to just "Terminal.app" might not be correctly
reflected in the settings.

Make sure that the terminal setting is removed in all cases, if it is
set to the default.

Amends f003234510

Change-Id: I9d099999f55b4003ac6e7f4a4b679b893eaffc90
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
2023-06-08 11:33:20 +00:00

147 lines
4.8 KiB
C++

// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "terminalcommand.h"
#include "algorithm.h"
#include "environment.h"
#include "hostosinfo.h"
#include <QCoreApplication>
#include <QFileInfo>
#include <QSettings>
namespace Utils {
static QSettings *s_settings = nullptr;
TerminalCommand::TerminalCommand(const FilePath &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<TerminalCommand>, 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()) {
return {"Terminal.app", "", ""};
} else if (HostOsInfo::isAnyUnixHost()) {
defaultTerm = {"xterm", "", "-e"};
const Environment env = Environment::systemEnvironment();
for (const TerminalCommand &term : *knownTerminals) {
const FilePath result = env.searchInPath(term.command.path());
if (!result.isEmpty()) {
defaultTerm = {result, term.openArgs, term.executeArgs, term.needsQuotes};
break;
}
}
}
}
return defaultTerm;
}
QVector<TerminalCommand> TerminalCommand::availableTerminalEmulators()
{
QVector<TerminalCommand> result;
if (HostOsInfo::isAnyUnixHost()) {
const Environment env = Environment::systemEnvironment();
for (const TerminalCommand &term : *knownTerminals) {
const FilePath command = env.searchInPath(term.command.path());
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() && s_settings->contains(kTerminalCommandKey)) {
FilePath command = FilePath::fromSettings(s_settings->value(kTerminalCommandKey));
// TODO Remove some time after Qt Creator 11
// Work around Qt Creator <= 10 writing the default terminal to the settings.
if (HostOsInfo::isMacHost() && command.endsWith("openTerminal.py"))
command = FilePath::fromString("Terminal.app");
return {command,
s_settings->value(kTerminalOpenOptionsKey).toString(),
s_settings->value(kTerminalExecuteOptionsKey).toString()};
}
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.toSettings());
s_settings->setValue(kTerminalOpenOptionsKey, term.openArgs);
s_settings->setValue(kTerminalExecuteOptionsKey, term.executeArgs);
}
}
}
} // Utils