forked from qt-creator/qt-creator
Terminal: Make shortcuts configurable
Fixes: QTCREATORBUG-28940 Change-Id: I1afe114c357243a8fa4f101b5eac80a766dc87b9 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -10,6 +10,7 @@ add_qtc_plugin(Terminal
|
|||||||
shellintegration.cpp shellintegration.h
|
shellintegration.cpp shellintegration.h
|
||||||
shellmodel.cpp shellmodel.h
|
shellmodel.cpp shellmodel.h
|
||||||
terminal.qrc
|
terminal.qrc
|
||||||
|
terminalcommands.cpp terminalcommands.h
|
||||||
terminalpane.cpp terminalpane.h
|
terminalpane.cpp terminalpane.h
|
||||||
terminalplugin.cpp terminalplugin.h
|
terminalplugin.cpp terminalplugin.h
|
||||||
terminalprocessimpl.cpp terminalprocessimpl.h
|
terminalprocessimpl.cpp terminalprocessimpl.h
|
||||||
|
|||||||
132
src/plugins/terminal/terminalcommands.cpp
Normal file
132
src/plugins/terminal/terminalcommands.cpp
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "terminalcommands.h"
|
||||||
|
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
|
||||||
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
|
//#include <coreplugin/context.h>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace Terminal {
|
||||||
|
|
||||||
|
constexpr char COPY[] = "Terminal.Copy";
|
||||||
|
constexpr char PASTE[] = "Terminal.Paste";
|
||||||
|
constexpr char CLEARSELECTION[] = "Terminal.ClearSelection";
|
||||||
|
|
||||||
|
constexpr char NEWTERMINAL[] = "Terminal.NewTerminal";
|
||||||
|
constexpr char CLOSETERMINAL[] = "Terminal.CloseTerminal";
|
||||||
|
constexpr char NEXTTERMINAL[] = "Terminal.NextTerminal";
|
||||||
|
constexpr char PREVTERMINAL[] = "Terminal.PrevTerminal";
|
||||||
|
constexpr char MINMAX[] = "Terminal.MinMax";
|
||||||
|
|
||||||
|
TerminalCommands &TerminalCommands::instance()
|
||||||
|
{
|
||||||
|
static TerminalCommands instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalCommands::TerminalCommands() {}
|
||||||
|
|
||||||
|
void TerminalCommands::init(const Core::Context &context)
|
||||||
|
{
|
||||||
|
initWidgetActions(context);
|
||||||
|
initPaneActions(context);
|
||||||
|
initGlobalCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommands::initWidgetActions(const Core::Context &context)
|
||||||
|
{
|
||||||
|
Command *command = ActionManager::instance()->registerAction(&m_widgetActions.copy,
|
||||||
|
COPY,
|
||||||
|
context);
|
||||||
|
command->setDefaultKeySequences(
|
||||||
|
{QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+C")
|
||||||
|
: QLatin1String("Ctrl+Shift+C")),
|
||||||
|
QKeySequence(Qt::Key_Return)});
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_widgetActions.paste, PASTE, context);
|
||||||
|
command->setDefaultKeySequence(QKeySequence(
|
||||||
|
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+V") : QLatin1String("Ctrl+Shift+V")));
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_widgetActions.clearSelection,
|
||||||
|
CLEARSELECTION);
|
||||||
|
command->setDefaultKeySequence(QKeySequence("Esc"));
|
||||||
|
m_commands.push_back(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommands::initPaneActions(const Core::Context &context)
|
||||||
|
{
|
||||||
|
Command *command = ActionManager::instance()->registerAction(&m_paneActions.newTerminal,
|
||||||
|
NEWTERMINAL,
|
||||||
|
context);
|
||||||
|
command->setDefaultKeySequence(QKeySequence(
|
||||||
|
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+T") : QLatin1String("Ctrl+Shift+T")));
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_paneActions.closeTerminal,
|
||||||
|
CLOSETERMINAL,
|
||||||
|
context);
|
||||||
|
command->setDefaultKeySequence(QKeySequence(
|
||||||
|
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+W") : QLatin1String("Ctrl+Shift+W")));
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_paneActions.nextTerminal,
|
||||||
|
NEXTTERMINAL,
|
||||||
|
context);
|
||||||
|
command->setDefaultKeySequences(
|
||||||
|
{QKeySequence("ALT+TAB"),
|
||||||
|
QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Shift+[")
|
||||||
|
: QLatin1String("Ctrl+PgUp"))});
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_paneActions.prevTerminal,
|
||||||
|
PREVTERMINAL,
|
||||||
|
context);
|
||||||
|
command->setDefaultKeySequences(
|
||||||
|
{QKeySequence("ALT+SHIFT+TAB"),
|
||||||
|
QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Shift+]")
|
||||||
|
: QLatin1String("Ctrl+PgDown"))});
|
||||||
|
m_commands.push_back(command);
|
||||||
|
|
||||||
|
command = ActionManager::instance()->registerAction(&m_paneActions.minMax, MINMAX, context);
|
||||||
|
command->setDefaultKeySequence(QKeySequence(
|
||||||
|
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Return") : QLatin1String("Alt+Return")));
|
||||||
|
m_commands.push_back(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalCommands::initGlobalCommands()
|
||||||
|
{
|
||||||
|
// Global commands we still want to allow
|
||||||
|
m_commands.push_back(ActionManager::command(Constants::ZOOM_IN));
|
||||||
|
m_commands.push_back(ActionManager::command(Constants::ZOOM_OUT));
|
||||||
|
m_commands.push_back(ActionManager::command(Constants::EXIT));
|
||||||
|
m_commands.push_back(ActionManager::command(Constants::OPTIONS));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TerminalCommands::triggerAction(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
for (const auto &command : TerminalCommands::instance().m_commands) {
|
||||||
|
if (!command->action()->isEnabled())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (const auto &shortcut : command->keySequences()) {
|
||||||
|
const auto result = shortcut.matches(QKeySequence(event->keyCombination()));
|
||||||
|
if (result == QKeySequence::ExactMatch) {
|
||||||
|
command->action()->trigger();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Terminal
|
||||||
59
src/plugins/terminal/terminalcommands.h
Normal file
59
src/plugins/terminal/terminalcommands.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "terminaltr.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class Command;
|
||||||
|
class Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Terminal {
|
||||||
|
|
||||||
|
struct WidgetActions
|
||||||
|
{
|
||||||
|
QAction copy{Tr::tr("Copy")};
|
||||||
|
QAction paste{Tr::tr("Paste")};
|
||||||
|
QAction clearSelection{Tr::tr("Clear Selection")};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PaneActions
|
||||||
|
{
|
||||||
|
QAction newTerminal{Tr::tr("New Terminal")};
|
||||||
|
QAction closeTerminal{Tr::tr("Close Terminal")};
|
||||||
|
QAction nextTerminal{Tr::tr("Next Terminal")};
|
||||||
|
QAction prevTerminal{Tr::tr("Previous Terminal")};
|
||||||
|
QAction minMax{Tr::tr("Minimize/Maximize Terminal")};
|
||||||
|
};
|
||||||
|
|
||||||
|
class TerminalCommands
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerminalCommands();
|
||||||
|
|
||||||
|
void init(const Core::Context &context);
|
||||||
|
static TerminalCommands &instance();
|
||||||
|
static WidgetActions &widgetActions() { return instance().m_widgetActions; }
|
||||||
|
static PaneActions &paneActions() { return instance().m_paneActions; }
|
||||||
|
|
||||||
|
static QList<QKeySequence> shortcutsFor(QAction *action);
|
||||||
|
|
||||||
|
static bool triggerAction(QKeyEvent *event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initWidgetActions(const Core::Context &context);
|
||||||
|
void initPaneActions(const Core::Context &context);
|
||||||
|
void initGlobalCommands();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WidgetActions m_widgetActions;
|
||||||
|
PaneActions m_paneActions;
|
||||||
|
QList<Core::Command *> m_commands;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Terminal
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
#include "terminalpane.h"
|
#include "terminalpane.h"
|
||||||
|
|
||||||
#include "shellmodel.h"
|
#include "shellmodel.h"
|
||||||
|
#include "terminalcommands.h"
|
||||||
#include "terminaltr.h"
|
#include "terminaltr.h"
|
||||||
#include "terminalwidget.h"
|
#include "terminalwidget.h"
|
||||||
#include "utils/terminalhooks.h"
|
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
|
#include <utils/terminalhooks.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QtWidgets/qwidget.h>
|
||||||
|
|
||||||
namespace Terminal {
|
namespace Terminal {
|
||||||
|
|
||||||
@@ -28,19 +30,33 @@ using namespace Utils::Terminal;
|
|||||||
|
|
||||||
TerminalPane::TerminalPane(QObject *parent)
|
TerminalPane::TerminalPane(QObject *parent)
|
||||||
: Core::IOutputPane(parent)
|
: Core::IOutputPane(parent)
|
||||||
|
, m_tabWidget(new QTabWidget)
|
||||||
{
|
{
|
||||||
Core::Context context("Terminal.Window");
|
setupContext("Terminal.Pane", m_tabWidget);
|
||||||
|
TerminalCommands::instance().init(Core::Context("Terminal.Pane"));
|
||||||
|
|
||||||
m_newTerminal.setIcon(Icons::PLUS_TOOLBAR.icon());
|
connect(this, &IOutputPane::zoomInRequested, this, [this] {
|
||||||
m_newTerminal.setToolTip(Tr::tr("Create a new Terminal."));
|
if (currentTerminal())
|
||||||
|
currentTerminal()->zoomIn();
|
||||||
|
});
|
||||||
|
connect(this, &IOutputPane::zoomOutRequested, this, [this] {
|
||||||
|
if (currentTerminal())
|
||||||
|
currentTerminal()->zoomOut();
|
||||||
|
});
|
||||||
|
|
||||||
connect(&m_newTerminal, &QAction::triggered, this, [this] { openTerminal({}); });
|
QAction &newTerminal = TerminalCommands::instance().paneActions().newTerminal;
|
||||||
|
QAction &closeTerminal = TerminalCommands::instance().paneActions().closeTerminal;
|
||||||
|
|
||||||
m_closeTerminal.setIcon(Icons::CLOSE_TOOLBAR.icon());
|
newTerminal.setIcon(Icons::PLUS_TOOLBAR.icon());
|
||||||
m_closeTerminal.setToolTip(Tr::tr("Close the current Terminal."));
|
newTerminal.setToolTip(Tr::tr("Create a new Terminal."));
|
||||||
m_closeTerminal.setEnabled(false);
|
|
||||||
|
|
||||||
connect(&m_closeTerminal, &QAction::triggered, this, [this] {
|
connect(&newTerminal, &QAction::triggered, this, [this] { openTerminal({}); });
|
||||||
|
|
||||||
|
closeTerminal.setIcon(Icons::CLOSE_TOOLBAR.icon());
|
||||||
|
closeTerminal.setToolTip(Tr::tr("Close the current Terminal."));
|
||||||
|
closeTerminal.setEnabled(false);
|
||||||
|
|
||||||
|
connect(&closeTerminal, &QAction::triggered, this, [this] {
|
||||||
removeTab(m_tabWidget->currentIndex());
|
removeTab(m_tabWidget->currentIndex());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,40 +84,40 @@ TerminalPane::TerminalPane(QObject *parent)
|
|||||||
addItems(shellModel->remote());
|
addItems(shellModel->remote());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_newTerminal.setMenu(shellMenu);
|
newTerminal.setMenu(shellMenu);
|
||||||
m_newTerminal.setShortcut(QKeySequence(
|
|
||||||
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+T") : QLatin1String("Ctrl+Shift+T")));
|
|
||||||
|
|
||||||
m_newTerminalButton->setDefaultAction(&m_newTerminal);
|
m_newTerminalButton->setDefaultAction(&newTerminal);
|
||||||
|
|
||||||
m_closeTerminalButton = new QToolButton();
|
m_closeTerminalButton = new QToolButton();
|
||||||
m_closeTerminalButton->setDefaultAction(&m_closeTerminal);
|
m_closeTerminalButton->setDefaultAction(&closeTerminal);
|
||||||
|
|
||||||
m_nextTerminal.setShortcut(QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Shift+[")
|
connect(&TerminalCommands::instance().paneActions().nextTerminal,
|
||||||
: QLatin1String("Ctrl+PgUp")));
|
&QAction::triggered,
|
||||||
m_prevTerminal.setShortcut(QKeySequence(HostOsInfo::isMacHost()
|
this,
|
||||||
? QLatin1String("Ctrl+Shift+]")
|
[this] {
|
||||||
: QLatin1String("Ctrl+PgDown")));
|
if (canNavigate())
|
||||||
|
goToNext();
|
||||||
|
});
|
||||||
|
connect(&TerminalCommands::instance().paneActions().prevTerminal,
|
||||||
|
&QAction::triggered,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
if (canPrevious())
|
||||||
|
goToPrev();
|
||||||
|
});
|
||||||
|
|
||||||
connect(&m_nextTerminal, &QAction::triggered, this, [this] {
|
connect(&TerminalCommands::instance().paneActions().minMax, &QAction::triggered, this, []() {
|
||||||
if (canNavigate())
|
|
||||||
goToNext();
|
|
||||||
});
|
|
||||||
connect(&m_prevTerminal, &QAction::triggered, this, [this] {
|
|
||||||
if (canPrevious())
|
|
||||||
goToPrev();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_minMaxAction.setShortcut(QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+Return")
|
|
||||||
: QLatin1String("Alt+Return")));
|
|
||||||
|
|
||||||
connect(&m_minMaxAction, &QAction::triggered, this, []() {
|
|
||||||
Core::Command *minMaxCommand = Core::ActionManager::command("Coreplugin.OutputPane.minmax");
|
Core::Command *minMaxCommand = Core::ActionManager::command("Coreplugin.OutputPane.minmax");
|
||||||
if (minMaxCommand)
|
if (minMaxCommand)
|
||||||
emit minMaxCommand->action()->triggered();
|
emit minMaxCommand->action()->triggered();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerminalPane::~TerminalPane()
|
||||||
|
{
|
||||||
|
delete m_tabWidget;
|
||||||
|
}
|
||||||
|
|
||||||
static std::optional<FilePath> startupProjectDirectory()
|
static std::optional<FilePath> startupProjectDirectory()
|
||||||
{
|
{
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject();
|
||||||
@@ -132,7 +148,7 @@ void TerminalPane::openTerminal(const OpenTerminalParameters ¶meters)
|
|||||||
|
|
||||||
m_tabWidget->currentWidget()->setFocus();
|
m_tabWidget->currentWidget()->setFocus();
|
||||||
|
|
||||||
m_closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
TerminalCommands::instance().paneActions().closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
||||||
emit navigateStateUpdate();
|
emit navigateStateUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +158,7 @@ void TerminalPane::addTerminal(TerminalWidget *terminal, const QString &title)
|
|||||||
m_tabWidget->setCurrentIndex(m_tabWidget->addTab(terminal, title));
|
m_tabWidget->setCurrentIndex(m_tabWidget->addTab(terminal, title));
|
||||||
setupTerminalWidget(terminal);
|
setupTerminalWidget(terminal);
|
||||||
|
|
||||||
m_closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
TerminalCommands::instance().paneActions().closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
||||||
emit navigateStateUpdate();
|
emit navigateStateUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,9 +177,8 @@ TerminalWidget *TerminalPane::stoppedTerminalWithId(const Id &identifier) const
|
|||||||
|
|
||||||
QWidget *TerminalPane::outputWidget(QWidget *parent)
|
QWidget *TerminalPane::outputWidget(QWidget *parent)
|
||||||
{
|
{
|
||||||
if (!m_tabWidget) {
|
if (!m_widgetInitialized) {
|
||||||
m_tabWidget = new QTabWidget(parent);
|
m_widgetInitialized = true;
|
||||||
|
|
||||||
m_tabWidget->setTabBarAutoHide(true);
|
m_tabWidget->setTabBarAutoHide(true);
|
||||||
m_tabWidget->setDocumentMode(true);
|
m_tabWidget->setDocumentMode(true);
|
||||||
m_tabWidget->setTabsClosable(true);
|
m_tabWidget->setTabsClosable(true);
|
||||||
@@ -192,7 +207,7 @@ void TerminalPane::removeTab(int index)
|
|||||||
if (m_tabWidget->count() > 1)
|
if (m_tabWidget->count() > 1)
|
||||||
delete m_tabWidget->widget(index);
|
delete m_tabWidget->widget(index);
|
||||||
|
|
||||||
m_closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
TerminalCommands::instance().paneActions().closeTerminal.setEnabled(m_tabWidget->count() > 1);
|
||||||
emit navigateStateUpdate();
|
emit navigateStateUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,13 +244,15 @@ void TerminalPane::setupTerminalWidget(TerminalWidget *terminal)
|
|||||||
|
|
||||||
if (!terminal->shellName().isEmpty())
|
if (!terminal->shellName().isEmpty())
|
||||||
setTabText(terminal);
|
setTabText(terminal);
|
||||||
|
|
||||||
terminal->addActions({&m_newTerminal, &m_nextTerminal, &m_prevTerminal, &m_minMaxAction});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QWidget *> TerminalPane::toolBarWidgets() const
|
QList<QWidget *> TerminalPane::toolBarWidgets() const
|
||||||
{
|
{
|
||||||
return {m_newTerminalButton, m_closeTerminalButton};
|
QList<QWidget *> widgets = IOutputPane::toolBarWidgets();
|
||||||
|
widgets.prepend(m_newTerminalButton);
|
||||||
|
widgets.prepend(m_closeTerminalButton);
|
||||||
|
|
||||||
|
return widgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TerminalPane::displayName() const
|
QString TerminalPane::displayName() const
|
||||||
|
|||||||
@@ -20,21 +20,22 @@ class TerminalPane : public Core::IOutputPane
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
TerminalPane(QObject *parent = nullptr);
|
TerminalPane(QObject *parent = nullptr);
|
||||||
|
~TerminalPane() override;
|
||||||
|
|
||||||
virtual QWidget *outputWidget(QWidget *parent);
|
QWidget *outputWidget(QWidget *parent) override;
|
||||||
virtual QList<QWidget *> toolBarWidgets() const;
|
QList<QWidget *> toolBarWidgets() const override;
|
||||||
virtual QString displayName() const;
|
QString displayName() const override;
|
||||||
virtual int priorityInStatusBar() const;
|
int priorityInStatusBar() const override;
|
||||||
virtual void clearContents();
|
void clearContents() override;
|
||||||
virtual void visibilityChanged(bool visible);
|
void visibilityChanged(bool visible) override;
|
||||||
virtual void setFocus();
|
void setFocus() override;
|
||||||
virtual bool hasFocus() const;
|
bool hasFocus() const override;
|
||||||
virtual bool canFocus() const;
|
bool canFocus() const override;
|
||||||
virtual bool canNavigate() const;
|
bool canNavigate() const override;
|
||||||
virtual bool canNext() const;
|
bool canNext() const override;
|
||||||
virtual bool canPrevious() const;
|
bool canPrevious() const override;
|
||||||
virtual void goToNext();
|
void goToNext() override;
|
||||||
virtual void goToPrev();
|
void goToPrev() override;
|
||||||
|
|
||||||
void openTerminal(const Utils::Terminal::OpenTerminalParameters ¶meters);
|
void openTerminal(const Utils::Terminal::OpenTerminalParameters ¶meters);
|
||||||
void addTerminal(TerminalWidget *terminal, const QString &title);
|
void addTerminal(TerminalWidget *terminal, const QString &title);
|
||||||
@@ -53,11 +54,7 @@ private:
|
|||||||
QToolButton *m_newTerminalButton{nullptr};
|
QToolButton *m_newTerminalButton{nullptr};
|
||||||
QToolButton *m_closeTerminalButton{nullptr};
|
QToolButton *m_closeTerminalButton{nullptr};
|
||||||
|
|
||||||
QAction m_newTerminal;
|
bool m_widgetInitialized{false};
|
||||||
QAction m_closeTerminal;
|
|
||||||
QAction m_nextTerminal;
|
|
||||||
QAction m_prevTerminal;
|
|
||||||
QAction m_minMaxAction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Terminal
|
} // namespace Terminal
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
#include "terminalwidget.h"
|
#include "terminalwidget.h"
|
||||||
#include "glyphcache.h"
|
#include "glyphcache.h"
|
||||||
|
#include "terminalcommands.h"
|
||||||
#include "terminalsettings.h"
|
#include "terminalsettings.h"
|
||||||
#include "terminalsurface.h"
|
#include "terminalsurface.h"
|
||||||
#include "terminaltr.h"
|
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -53,11 +53,6 @@ static constexpr std::chrono::milliseconds minRefreshInterval = 1s / 30;
|
|||||||
|
|
||||||
TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &openParameters)
|
TerminalWidget::TerminalWidget(QWidget *parent, const OpenTerminalParameters &openParameters)
|
||||||
: QAbstractScrollArea(parent)
|
: QAbstractScrollArea(parent)
|
||||||
, m_copyAction(Tr::tr("Copy"))
|
|
||||||
, m_pasteAction(Tr::tr("Paste"))
|
|
||||||
, m_clearSelectionAction(Tr::tr("Clear Selection"))
|
|
||||||
, m_zoomInAction(Tr::tr("Zoom In"))
|
|
||||||
, m_zoomOutAction(Tr::tr("Zoom Out"))
|
|
||||||
, m_openParameters(openParameters)
|
, m_openParameters(openParameters)
|
||||||
, m_lastFlush(std::chrono::system_clock::now())
|
, m_lastFlush(std::chrono::system_clock::now())
|
||||||
, m_lastDoubleClick(std::chrono::system_clock::now())
|
, m_lastDoubleClick(std::chrono::system_clock::now())
|
||||||
@@ -224,27 +219,20 @@ void TerminalWidget::setupColors()
|
|||||||
|
|
||||||
void TerminalWidget::setupActions()
|
void TerminalWidget::setupActions()
|
||||||
{
|
{
|
||||||
m_copyAction.setEnabled(false);
|
WidgetActions &a = TerminalCommands::widgetActions();
|
||||||
m_copyAction.setShortcuts(
|
|
||||||
{QKeySequence(HostOsInfo::isMacHost() ? QLatin1String("Ctrl+C")
|
|
||||||
: QLatin1String("Ctrl+Shift+C")),
|
|
||||||
QKeySequence(Qt::Key_Return)});
|
|
||||||
m_pasteAction.setShortcut(QKeySequence(
|
|
||||||
HostOsInfo::isMacHost() ? QLatin1String("Ctrl+V") : QLatin1String("Ctrl+Shift+V")));
|
|
||||||
|
|
||||||
m_clearSelectionAction.setShortcut(QKeySequence("Esc"));
|
auto ifHasFocus = [this](void (TerminalWidget::*f)()) {
|
||||||
|
return [this, f] {
|
||||||
|
if (hasFocus())
|
||||||
|
(this->*f)();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
m_zoomInAction.setShortcuts({QKeySequence("Ctrl++"), QKeySequence("Ctrl+Shift++")});
|
// clang-format off
|
||||||
m_zoomOutAction.setShortcut(QKeySequence("Ctrl+-"));
|
connect(&a.copy, &QAction::triggered, this, ifHasFocus(&TerminalWidget::copyToClipboard));
|
||||||
|
connect(&a.paste, &QAction::triggered, this, ifHasFocus(&TerminalWidget::pasteFromClipboard));
|
||||||
connect(&m_copyAction, &QAction::triggered, this, &TerminalWidget::copyToClipboard);
|
connect(&a.clearSelection, &QAction::triggered, this, ifHasFocus(&TerminalWidget::clearSelection));
|
||||||
connect(&m_pasteAction, &QAction::triggered, this, &TerminalWidget::pasteFromClipboard);
|
// clang-format on
|
||||||
connect(&m_clearSelectionAction, &QAction::triggered, this, &TerminalWidget::clearSelection);
|
|
||||||
connect(&m_zoomInAction, &QAction::triggered, this, &TerminalWidget::zoomIn);
|
|
||||||
connect(&m_zoomOutAction, &QAction::triggered, this, &TerminalWidget::zoomOut);
|
|
||||||
|
|
||||||
addActions(
|
|
||||||
{&m_copyAction, &m_pasteAction, &m_clearSelectionAction, &m_zoomInAction, &m_zoomOutAction});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalWidget::writeToPty(const QByteArray &data)
|
void TerminalWidget::writeToPty(const QByteArray &data)
|
||||||
@@ -342,6 +330,14 @@ QColor TerminalWidget::toQColor(std::variant<int, QColor> color) const
|
|||||||
return std::get<QColor>(color);
|
return std::get<QColor>(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalWidget::updateCopyState()
|
||||||
|
{
|
||||||
|
if (!hasFocus())
|
||||||
|
return;
|
||||||
|
|
||||||
|
TerminalCommands::widgetActions().copy.setEnabled(m_selection.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
void TerminalWidget::setFont(const QFont &font)
|
void TerminalWidget::setFont(const QFont &font)
|
||||||
{
|
{
|
||||||
m_font = font;
|
m_font = font;
|
||||||
@@ -364,33 +360,10 @@ void TerminalWidget::setFont(const QFont &font)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction &TerminalWidget::copyAction()
|
void TerminalWidget::copyToClipboard()
|
||||||
{
|
{
|
||||||
return m_copyAction;
|
QTC_ASSERT(m_selection.has_value(), return);
|
||||||
}
|
|
||||||
|
|
||||||
QAction &TerminalWidget::pasteAction()
|
|
||||||
{
|
|
||||||
return m_pasteAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction &TerminalWidget::clearSelectionAction()
|
|
||||||
{
|
|
||||||
return m_clearSelectionAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction &TerminalWidget::zoomInAction()
|
|
||||||
{
|
|
||||||
return m_zoomInAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction &TerminalWidget::zoomOutAction()
|
|
||||||
{
|
|
||||||
return m_zoomOutAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TerminalWidget::copyToClipboard() const
|
|
||||||
{
|
|
||||||
QString text = textFromSelection();
|
QString text = textFromSelection();
|
||||||
|
|
||||||
qCDebug(selectionLog) << "Copied to clipboard: " << text;
|
qCDebug(selectionLog) << "Copied to clipboard: " << text;
|
||||||
@@ -491,10 +464,10 @@ bool TerminalWidget::setSelection(const std::optional<Selection> &selection)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_copyAction.setEnabled(selection.has_value());
|
|
||||||
|
|
||||||
m_selection = selection;
|
m_selection = selection;
|
||||||
|
|
||||||
|
updateCopyState();
|
||||||
|
|
||||||
if (m_selection && m_selection->final) {
|
if (m_selection && m_selection->final) {
|
||||||
qCDebug(selectionLog) << "Copy enabled:" << selection.has_value();
|
qCDebug(selectionLog) << "Copy enabled:" << selection.has_value();
|
||||||
|
|
||||||
@@ -958,25 +931,7 @@ void TerminalWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
m_cursorBlinkState = true;
|
m_cursorBlinkState = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool actionTriggered = false;
|
if (TerminalCommands::triggerAction(event)) {
|
||||||
for (const auto &action : actions()) {
|
|
||||||
if (!action->isEnabled())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const auto &shortcut : action->shortcuts()) {
|
|
||||||
const auto result = shortcut.matches(QKeySequence(event->keyCombination()));
|
|
||||||
if (result == QKeySequence::ExactMatch) {
|
|
||||||
action->trigger();
|
|
||||||
actionTriggered = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actionTriggered)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actionTriggered) {
|
|
||||||
setSelection(std::nullopt);
|
setSelection(std::nullopt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1067,6 +1022,7 @@ void TerminalWidget::focusInEvent(QFocusEvent *)
|
|||||||
{
|
{
|
||||||
updateViewport();
|
updateViewport();
|
||||||
configBlinkTimer();
|
configBlinkTimer();
|
||||||
|
updateCopyState();
|
||||||
}
|
}
|
||||||
void TerminalWidget::focusOutEvent(QFocusEvent *)
|
void TerminalWidget::focusOutEvent(QFocusEvent *)
|
||||||
{
|
{
|
||||||
@@ -1123,10 +1079,10 @@ void TerminalWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
updateViewport();
|
updateViewport();
|
||||||
} else if (event->button() == Qt::RightButton) {
|
} else if (event->button() == Qt::RightButton) {
|
||||||
if (m_selection) {
|
if (m_selection) {
|
||||||
m_copyAction.trigger();
|
copyToClipboard();
|
||||||
setSelection(std::nullopt);
|
setSelection(std::nullopt);
|
||||||
} else {
|
} else {
|
||||||
m_pasteAction.trigger();
|
pasteFromClipboard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,15 +29,7 @@ public:
|
|||||||
|
|
||||||
void setFont(const QFont &font);
|
void setFont(const QFont &font);
|
||||||
|
|
||||||
QAction ©Action();
|
void copyToClipboard();
|
||||||
QAction &pasteAction();
|
|
||||||
|
|
||||||
QAction &clearSelectionAction();
|
|
||||||
|
|
||||||
QAction &zoomInAction();
|
|
||||||
QAction &zoomOutAction();
|
|
||||||
|
|
||||||
void copyToClipboard() const;
|
|
||||||
void pasteFromClipboard();
|
void pasteFromClipboard();
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
@@ -168,6 +160,8 @@ protected:
|
|||||||
|
|
||||||
QColor toQColor(std::variant<int, QColor> color) const;
|
QColor toQColor(std::variant<int, QColor> color) const;
|
||||||
|
|
||||||
|
void updateCopyState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||||
std::unique_ptr<Internal::TerminalSurface> m_surface;
|
std::unique_ptr<Internal::TerminalSurface> m_surface;
|
||||||
@@ -192,14 +186,6 @@ private:
|
|||||||
QPoint end;
|
QPoint end;
|
||||||
} m_activeMouseSelect;
|
} m_activeMouseSelect;
|
||||||
|
|
||||||
QAction m_copyAction;
|
|
||||||
QAction m_pasteAction;
|
|
||||||
|
|
||||||
QAction m_clearSelectionAction;
|
|
||||||
|
|
||||||
QAction m_zoomInAction;
|
|
||||||
QAction m_zoomOutAction;
|
|
||||||
|
|
||||||
QTimer m_flushDelayTimer;
|
QTimer m_flushDelayTimer;
|
||||||
|
|
||||||
QTimer m_scrollTimer;
|
QTimer m_scrollTimer;
|
||||||
|
|||||||
Reference in New Issue
Block a user