2023-02-23 12:47:39 +01:00
|
|
|
// Copyright (C) 2022 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
|
|
|
|
|
|
|
|
|
#include "terminalpane.h"
|
|
|
|
|
|
2023-02-25 10:47:21 +01:00
|
|
|
#include "shellmodel.h"
|
2023-06-06 09:37:13 +02:00
|
|
|
#include "shortcutmap.h"
|
2023-05-23 07:15:42 +02:00
|
|
|
#include "terminalconstants.h"
|
|
|
|
|
#include "terminalicons.h"
|
2023-03-24 22:02:23 +01:00
|
|
|
#include "terminalsettings.h"
|
2023-02-23 12:47:39 +01:00
|
|
|
#include "terminaltr.h"
|
|
|
|
|
#include "terminalwidget.h"
|
|
|
|
|
|
|
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2023-05-23 07:15:42 +02:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2023-02-23 12:47:39 +01:00
|
|
|
#include <coreplugin/icontext.h>
|
2023-03-24 22:02:23 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2023-05-23 07:15:42 +02:00
|
|
|
#include <coreplugin/locator/locatorconstants.h>
|
2023-02-23 12:47:39 +01:00
|
|
|
|
2023-03-06 11:54:21 +01:00
|
|
|
#include <projectexplorer/project.h>
|
|
|
|
|
#include <projectexplorer/projectmanager.h>
|
|
|
|
|
|
2023-02-23 15:21:26 +01:00
|
|
|
#include <utils/algorithm.h>
|
|
|
|
|
#include <utils/environment.h>
|
2023-03-23 11:04:54 +01:00
|
|
|
#include <utils/terminalhooks.h>
|
2023-02-23 12:47:39 +01:00
|
|
|
#include <utils/utilsicons.h>
|
|
|
|
|
|
2023-07-03 14:33:21 +03:00
|
|
|
#include <QFileIconProvider>
|
2023-02-23 15:21:26 +01:00
|
|
|
#include <QMenu>
|
|
|
|
|
#include <QStandardPaths>
|
2023-03-23 12:28:44 +01:00
|
|
|
#include <QToolButton>
|
2023-02-23 15:21:26 +01:00
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
namespace Terminal {
|
|
|
|
|
|
2023-02-23 15:21:26 +01:00
|
|
|
using namespace Utils;
|
2023-03-07 17:55:38 +01:00
|
|
|
using namespace Utils::Terminal;
|
2023-05-23 07:15:42 +02:00
|
|
|
using namespace Core;
|
2023-02-23 15:21:26 +01:00
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
TerminalPane::TerminalPane(QObject *parent)
|
2023-05-23 07:15:42 +02:00
|
|
|
: IOutputPane(parent)
|
2023-06-06 09:37:13 +02:00
|
|
|
, m_selfContext("Terminal.Pane")
|
2023-02-23 12:47:39 +01:00
|
|
|
{
|
2023-06-06 09:37:13 +02:00
|
|
|
setupContext(m_selfContext, &m_tabWidget);
|
2023-03-24 12:53:21 +01:00
|
|
|
setZoomButtonsEnabled(true);
|
|
|
|
|
|
2023-03-23 11:04:54 +01:00
|
|
|
connect(this, &IOutputPane::zoomInRequested, this, [this] {
|
|
|
|
|
if (currentTerminal())
|
|
|
|
|
currentTerminal()->zoomIn();
|
|
|
|
|
});
|
|
|
|
|
connect(this, &IOutputPane::zoomOutRequested, this, [this] {
|
|
|
|
|
if (currentTerminal())
|
|
|
|
|
currentTerminal()->zoomOut();
|
|
|
|
|
});
|
|
|
|
|
|
2023-05-23 07:15:42 +02:00
|
|
|
initActions();
|
2023-02-23 12:47:39 +01:00
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
m_lockKeyboardButton = new QToolButton();
|
|
|
|
|
m_lockKeyboardButton->setDefaultAction(&lockKeyboard);
|
|
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
m_newTerminalButton = new QToolButton();
|
2023-03-23 11:04:54 +01:00
|
|
|
m_newTerminalButton->setDefaultAction(&newTerminal);
|
2023-02-23 12:47:39 +01:00
|
|
|
|
|
|
|
|
m_closeTerminalButton = new QToolButton();
|
2023-03-23 11:04:54 +01:00
|
|
|
m_closeTerminalButton->setDefaultAction(&closeTerminal);
|
|
|
|
|
|
2023-03-23 12:28:44 +01:00
|
|
|
m_openSettingsButton = new QToolButton();
|
2023-05-23 07:15:42 +02:00
|
|
|
m_openSettingsButton->setToolTip(Tr::tr("Configure..."));
|
2023-03-23 12:28:44 +01:00
|
|
|
m_openSettingsButton->setIcon(Icons::SETTINGS_TOOLBAR.icon());
|
|
|
|
|
|
|
|
|
|
connect(m_openSettingsButton, &QToolButton::clicked, m_openSettingsButton, []() {
|
2023-05-23 07:15:42 +02:00
|
|
|
ICore::showOptionsDialog("Terminal.General");
|
2023-03-23 12:28:44 +01:00
|
|
|
});
|
2023-03-24 22:02:23 +01:00
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
const auto updateEscButton = [this] {
|
2023-05-23 07:15:42 +02:00
|
|
|
m_escSettingButton->setChecked(TerminalSettings::instance().sendEscapeToTerminal());
|
2023-05-23 12:50:09 +02:00
|
|
|
static const QString escKey
|
|
|
|
|
= QKeySequence(Qt::Key_Escape).toString(QKeySequence::NativeText);
|
|
|
|
|
static const QString shiftEsc = QKeySequence(
|
|
|
|
|
QKeyCombination(Qt::ShiftModifier, Qt::Key_Escape))
|
|
|
|
|
.toString(QKeySequence::NativeText);
|
2023-03-24 22:02:23 +01:00
|
|
|
if (TerminalSettings::instance().sendEscapeToTerminal.value()) {
|
2023-03-27 12:00:27 +02:00
|
|
|
m_escSettingButton->setText(escKey);
|
2023-06-19 11:53:33 +02:00
|
|
|
m_escSettingButton->setToolTip(Tr::tr("Sends Esc to terminal instead of Qt Creator."));
|
2023-03-24 22:02:23 +01:00
|
|
|
} else {
|
2023-03-27 12:00:27 +02:00
|
|
|
m_escSettingButton->setText(shiftEsc);
|
2023-06-19 11:53:33 +02:00
|
|
|
m_escSettingButton->setToolTip(Tr::tr("Press %1 to send Esc to terminal.").arg(shiftEsc));
|
2023-03-24 22:02:23 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_escSettingButton = new QToolButton();
|
|
|
|
|
m_escSettingButton->setCheckable(true);
|
|
|
|
|
|
|
|
|
|
updateEscButton();
|
|
|
|
|
|
2023-06-05 09:13:03 +02:00
|
|
|
connect(m_escSettingButton, &QToolButton::toggled, this, [this, updateEscButton] {
|
2023-03-24 22:02:23 +01:00
|
|
|
TerminalSettings::instance().sendEscapeToTerminal.setValue(m_escSettingButton->isChecked());
|
2023-05-23 07:15:42 +02:00
|
|
|
TerminalSettings::instance().writeSettings(ICore::settings());
|
2023-06-05 09:13:03 +02:00
|
|
|
updateEscButton();
|
2023-03-24 22:02:23 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(&TerminalSettings::instance(), &TerminalSettings::applied, this, updateEscButton);
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
TerminalPane::~TerminalPane() {}
|
2023-03-23 11:04:54 +01:00
|
|
|
|
2023-03-06 11:54:21 +01:00
|
|
|
static std::optional<FilePath> startupProjectDirectory()
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
const ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject();
|
2023-03-06 11:54:21 +01:00
|
|
|
if (!project)
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
|
|
return project->projectDirectory();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:55:38 +01:00
|
|
|
void TerminalPane::openTerminal(const OpenTerminalParameters ¶meters)
|
2023-02-23 12:47:39 +01:00
|
|
|
{
|
2023-03-07 17:55:38 +01:00
|
|
|
OpenTerminalParameters parametersCopy{parameters};
|
2023-03-06 11:54:21 +01:00
|
|
|
|
2023-03-07 17:55:38 +01:00
|
|
|
if (!parametersCopy.workingDirectory) {
|
2023-03-06 11:54:21 +01:00
|
|
|
const std::optional<FilePath> projectDir = startupProjectDirectory();
|
|
|
|
|
if (projectDir) {
|
2023-03-07 17:55:38 +01:00
|
|
|
if (!parametersCopy.shellCommand
|
|
|
|
|
|| parametersCopy.shellCommand->executable().ensureReachable(*projectDir)) {
|
|
|
|
|
parametersCopy.workingDirectory = *projectDir;
|
2023-03-06 11:54:21 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
const auto terminalWidget = new TerminalWidget(&m_tabWidget, parametersCopy);
|
2023-06-06 09:37:13 +02:00
|
|
|
|
|
|
|
|
using namespace Constants;
|
|
|
|
|
terminalWidget->unlockGlobalAction("Coreplugin.OutputPane.minmax");
|
|
|
|
|
terminalWidget->unlockGlobalAction(Core::Constants::LOCATE);
|
|
|
|
|
terminalWidget->unlockGlobalAction(NEWTERMINAL);
|
|
|
|
|
terminalWidget->unlockGlobalAction(NEXTTERMINAL);
|
|
|
|
|
terminalWidget->unlockGlobalAction(PREVTERMINAL);
|
|
|
|
|
|
2023-07-03 14:33:21 +03:00
|
|
|
QIcon icon;
|
|
|
|
|
if (HostOsInfo::isWindowsHost()) {
|
|
|
|
|
icon = parametersCopy.icon;
|
|
|
|
|
if (icon.isNull()) {
|
|
|
|
|
QFileIconProvider iconProvider;
|
|
|
|
|
const FilePath command = parametersCopy.shellCommand
|
|
|
|
|
? parametersCopy.shellCommand->executable()
|
|
|
|
|
: TerminalSettings::instance().shell.filePath();
|
|
|
|
|
icon = iconProvider.icon(command.toFileInfo());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_tabWidget.setCurrentIndex(m_tabWidget.addTab(terminalWidget, icon, Tr::tr("Terminal")));
|
2023-03-02 16:59:03 +01:00
|
|
|
setupTerminalWidget(terminalWidget);
|
2023-02-23 12:47:39 +01:00
|
|
|
|
2023-06-08 15:10:21 +02:00
|
|
|
if (!m_isVisible)
|
|
|
|
|
emit showPage(IOutputPane::ModeSwitch);
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.currentWidget()->setFocus();
|
2023-02-25 10:47:21 +01:00
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
emit navigateStateUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::addTerminal(TerminalWidget *terminal, const QString &title)
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.setCurrentIndex(m_tabWidget.addTab(terminal, title));
|
2023-03-02 16:59:03 +01:00
|
|
|
setupTerminalWidget(terminal);
|
2023-02-23 12:47:39 +01:00
|
|
|
|
2023-06-08 15:10:21 +02:00
|
|
|
if (!m_isVisible)
|
|
|
|
|
emit showPage(IOutputPane::ModeSwitch);
|
|
|
|
|
|
|
|
|
|
terminal->setFocus();
|
|
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
emit navigateStateUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 10:29:55 +02:00
|
|
|
void TerminalPane::ensureVisible(TerminalWidget *terminal)
|
|
|
|
|
{
|
|
|
|
|
if (!m_isVisible)
|
2023-05-11 15:47:25 +02:00
|
|
|
emit showPage(IOutputPane::ModeSwitch);
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.setCurrentWidget(terminal);
|
2023-05-09 10:29:55 +02:00
|
|
|
terminal->setFocus();
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
TerminalWidget *TerminalPane::stoppedTerminalWithId(Id identifier) const
|
2023-03-07 17:55:38 +01:00
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
for (int i = 0; i < m_tabWidget.count(); ++i) {
|
|
|
|
|
const auto terminal = qobject_cast<TerminalWidget *>(m_tabWidget.widget(i));
|
|
|
|
|
if (terminal && terminal->processState() == QProcess::NotRunning
|
|
|
|
|
&& terminal->identifier() == identifier)
|
2023-03-07 17:55:38 +01:00
|
|
|
return terminal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
QWidget *TerminalPane::outputWidget(QWidget *parent)
|
|
|
|
|
{
|
2023-06-01 03:58:39 +02:00
|
|
|
Q_UNUSED(parent)
|
2023-03-23 11:04:54 +01:00
|
|
|
if (!m_widgetInitialized) {
|
|
|
|
|
m_widgetInitialized = true;
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.setTabBarAutoHide(false);
|
|
|
|
|
m_tabWidget.setDocumentMode(true);
|
|
|
|
|
m_tabWidget.setTabsClosable(true);
|
|
|
|
|
m_tabWidget.setMovable(true);
|
2023-02-23 12:47:39 +01:00
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
connect(&m_tabWidget, &QTabWidget::tabCloseRequested, this, [this](int index) {
|
2023-02-23 12:47:39 +01:00
|
|
|
removeTab(index);
|
|
|
|
|
});
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
connect(&m_tabWidget, &QTabWidget::currentChanged, this, [this](int index) {
|
|
|
|
|
if (auto widget = m_tabWidget.widget(index))
|
2023-03-24 12:38:55 +01:00
|
|
|
widget->setFocus();
|
2023-03-28 09:21:01 +02:00
|
|
|
else
|
|
|
|
|
emit hidePage();
|
2023-03-24 12:38:55 +01:00
|
|
|
});
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
return &m_tabWidget;
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TerminalWidget *TerminalPane::currentTerminal() const
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
return static_cast<TerminalWidget *>(m_tabWidget.currentWidget());
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::removeTab(int index)
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
delete m_tabWidget.widget(index);
|
2023-02-23 12:47:39 +01:00
|
|
|
emit navigateStateUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-02 16:59:03 +01:00
|
|
|
void TerminalPane::setupTerminalWidget(TerminalWidget *terminal)
|
|
|
|
|
{
|
|
|
|
|
if (!terminal)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-07-03 12:21:30 +03:00
|
|
|
const auto setTabText = [this, terminal] {
|
2023-05-23 12:50:09 +02:00
|
|
|
const int index = m_tabWidget.indexOf(terminal);
|
2023-07-03 12:21:30 +03:00
|
|
|
m_tabWidget.setTabText(index, terminal->title());
|
2023-03-02 16:59:03 +01:00
|
|
|
};
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
connect(terminal, &TerminalWidget::started, this, setTabText);
|
|
|
|
|
connect(terminal, &TerminalWidget::cwdChanged, this, setTabText);
|
|
|
|
|
connect(terminal, &TerminalWidget::commandChanged, this, setTabText);
|
2023-07-03 12:21:30 +03:00
|
|
|
connect(terminal, &TerminalWidget::titleChanged, this, setTabText);
|
2023-03-10 13:55:17 +01:00
|
|
|
|
2023-03-02 16:59:03 +01:00
|
|
|
if (!terminal->shellName().isEmpty())
|
2023-05-23 12:50:09 +02:00
|
|
|
setTabText();
|
2023-03-02 16:59:03 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-23 07:15:42 +02:00
|
|
|
void TerminalPane::initActions()
|
|
|
|
|
{
|
|
|
|
|
createShellMenu();
|
|
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
lockKeyboard.setCheckable(true);
|
|
|
|
|
lockKeyboard.setChecked(TerminalSettings::instance().lockKeyboard());
|
|
|
|
|
|
|
|
|
|
auto updateLockKeyboard = [this](bool locked) {
|
|
|
|
|
TerminalSettings::instance().lockKeyboard.setValue(locked);
|
|
|
|
|
if (locked) {
|
2023-06-08 15:46:14 +02:00
|
|
|
lockKeyboard.setIcon(LOCK_KEYBOARD_ICON.icon());
|
2023-06-19 11:53:33 +02:00
|
|
|
lockKeyboard.setToolTip(Tr::tr("Sends keyboard shortcuts to Terminal."));
|
2023-06-06 09:37:13 +02:00
|
|
|
} else {
|
2023-06-08 15:46:14 +02:00
|
|
|
lockKeyboard.setIcon(UNLOCK_KEYBOARD_ICON.icon());
|
2023-06-19 11:53:33 +02:00
|
|
|
lockKeyboard.setToolTip(Tr::tr("Sends keyboard shortcuts to Qt Creator."));
|
2023-06-06 09:37:13 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
updateLockKeyboard(TerminalSettings::instance().lockKeyboard());
|
|
|
|
|
connect(&lockKeyboard, &QAction::toggled, this, updateLockKeyboard);
|
|
|
|
|
|
2023-05-23 07:15:42 +02:00
|
|
|
newTerminal.setText(Tr::tr("New Terminal"));
|
|
|
|
|
newTerminal.setIcon(NEW_TERMINAL_ICON.icon());
|
|
|
|
|
newTerminal.setToolTip(Tr::tr("Create a new Terminal."));
|
|
|
|
|
newTerminal.setMenu(&m_shellMenu);
|
|
|
|
|
|
|
|
|
|
nextTerminal.setText(Tr::tr("Next Terminal"));
|
|
|
|
|
prevTerminal.setText(Tr::tr("Previous Terminal"));
|
|
|
|
|
|
|
|
|
|
closeTerminal.setIcon(CLOSE_TERMINAL_ICON.icon());
|
|
|
|
|
closeTerminal.setToolTip(Tr::tr("Close the current Terminal."));
|
|
|
|
|
|
|
|
|
|
using namespace Constants;
|
|
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
Command *cmd = ActionManager::registerAction(&newTerminal, NEWTERMINAL, m_selfContext);
|
|
|
|
|
cmd->setDefaultKeySequences({QKeySequence(
|
|
|
|
|
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+T") : QLatin1String("Ctrl+Shift+T"))});
|
2023-05-23 07:15:42 +02:00
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
ActionManager::registerAction(&nextTerminal, NEXTTERMINAL, m_selfContext)
|
2023-05-23 07:15:42 +02:00
|
|
|
->setDefaultKeySequences(
|
|
|
|
|
{QKeySequence("Alt+Tab"),
|
|
|
|
|
QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Shift+[")
|
|
|
|
|
: QLatin1String("Ctrl+PgUp"))});
|
|
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
ActionManager::registerAction(&prevTerminal, PREVTERMINAL, m_selfContext)
|
2023-05-23 07:15:42 +02:00
|
|
|
->setDefaultKeySequences(
|
|
|
|
|
{QKeySequence("Alt+Shift+Tab"),
|
|
|
|
|
QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Shift+]")
|
|
|
|
|
: QLatin1String("Ctrl+PgDown"))});
|
|
|
|
|
|
|
|
|
|
connect(&newTerminal, &QAction::triggered, this, [this] { openTerminal({}); });
|
|
|
|
|
connect(&closeTerminal, &QAction::triggered, this, [this] {
|
|
|
|
|
removeTab(m_tabWidget.currentIndex());
|
|
|
|
|
});
|
|
|
|
|
connect(&nextTerminal, &QAction::triggered, this, [this] {
|
|
|
|
|
if (canNavigate())
|
|
|
|
|
goToNext();
|
|
|
|
|
});
|
|
|
|
|
connect(&prevTerminal, &QAction::triggered, this, [this] {
|
|
|
|
|
if (canPrevious())
|
|
|
|
|
goToPrev();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::createShellMenu()
|
|
|
|
|
{
|
|
|
|
|
const Internal::ShellModel *shellModel = new Internal::ShellModel(&m_shellMenu);
|
|
|
|
|
|
|
|
|
|
connect(&m_shellMenu, &QMenu::aboutToShow, &m_shellMenu, [shellModel, this] {
|
|
|
|
|
m_shellMenu.clear();
|
|
|
|
|
|
|
|
|
|
const auto addItems = [this](const QList<Internal::ShellModelItem> &items) {
|
|
|
|
|
for (const Internal::ShellModelItem &item : items) {
|
2023-07-03 14:33:21 +03:00
|
|
|
QAction *action = new QAction(item.openParameters.icon, item.name, &m_shellMenu);
|
2023-05-23 07:15:42 +02:00
|
|
|
|
|
|
|
|
connect(action, &QAction::triggered, action, [item, this]() {
|
|
|
|
|
openTerminal(item.openParameters);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_shellMenu.addAction(action);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
addItems(shellModel->local());
|
|
|
|
|
m_shellMenu.addSection(Tr::tr("Devices"));
|
|
|
|
|
addItems(shellModel->remote());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
QList<QWidget *> TerminalPane::toolBarWidgets() const
|
|
|
|
|
{
|
2023-03-23 11:04:54 +01:00
|
|
|
QList<QWidget *> widgets = IOutputPane::toolBarWidgets();
|
2023-06-06 09:37:13 +02:00
|
|
|
|
2023-03-23 11:04:54 +01:00
|
|
|
widgets.prepend(m_newTerminalButton);
|
|
|
|
|
widgets.prepend(m_closeTerminalButton);
|
|
|
|
|
|
2023-06-06 09:37:13 +02:00
|
|
|
return widgets << m_openSettingsButton << m_lockKeyboardButton << m_escSettingButton;
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString TerminalPane::displayName() const
|
|
|
|
|
{
|
|
|
|
|
return Tr::tr("Terminal");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TerminalPane::priorityInStatusBar() const
|
|
|
|
|
{
|
|
|
|
|
return 50;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::clearContents()
|
|
|
|
|
{
|
|
|
|
|
if (const auto t = currentTerminal())
|
|
|
|
|
t->clearContents();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 09:21:01 +02:00
|
|
|
void TerminalPane::visibilityChanged(bool visible)
|
|
|
|
|
{
|
|
|
|
|
if (m_isVisible == visible)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_isVisible = visible;
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
if (visible && m_tabWidget.count() == 0)
|
2023-03-28 09:21:01 +02:00
|
|
|
openTerminal({});
|
|
|
|
|
|
|
|
|
|
IOutputPane::visibilityChanged(visible);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 12:47:39 +01:00
|
|
|
void TerminalPane::setFocus()
|
|
|
|
|
{
|
|
|
|
|
if (const auto t = currentTerminal())
|
|
|
|
|
t->setFocus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TerminalPane::hasFocus() const
|
|
|
|
|
{
|
|
|
|
|
if (const auto t = currentTerminal())
|
2023-02-27 11:06:14 +01:00
|
|
|
return t->hasFocus();
|
2023-02-23 12:47:39 +01:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TerminalPane::canFocus() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TerminalPane::canNavigate() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TerminalPane::canNext() const
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
return m_tabWidget.count() > 1;
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TerminalPane::canPrevious() const
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
return m_tabWidget.count() > 1;
|
2023-02-23 12:47:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::goToNext()
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
int nextIndex = m_tabWidget.currentIndex() + 1;
|
|
|
|
|
if (nextIndex >= m_tabWidget.count())
|
2023-03-02 18:13:27 +01:00
|
|
|
nextIndex = 0;
|
|
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.setCurrentIndex(nextIndex);
|
2023-02-23 12:47:39 +01:00
|
|
|
emit navigateStateUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TerminalPane::goToPrev()
|
|
|
|
|
{
|
2023-05-23 12:50:09 +02:00
|
|
|
int prevIndex = m_tabWidget.currentIndex() - 1;
|
2023-03-02 18:13:27 +01:00
|
|
|
if (prevIndex < 0)
|
2023-05-23 12:50:09 +02:00
|
|
|
prevIndex = m_tabWidget.count() - 1;
|
2023-03-02 18:13:27 +01:00
|
|
|
|
2023-05-23 12:50:09 +02:00
|
|
|
m_tabWidget.setCurrentIndex(prevIndex);
|
2023-02-23 12:47:39 +01:00
|
|
|
emit navigateStateUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Terminal
|