forked from qt-creator/qt-creator
Fix "open terminal with environment" functionality
... for RemoteLinux. We now open a *remote* terminal, as we should. Change-Id: I84f73bbfcb6132717a30f5ef7c8d9d56d854a609 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -53,6 +53,7 @@ public:
|
||||
explicit EnvironmentAspectWidget(EnvironmentAspect *aspect, QWidget *additionalWidget = nullptr);
|
||||
|
||||
virtual EnvironmentAspect *aspect() const;
|
||||
EnvironmentWidget *envWidget() const { return m_environmentWidget; }
|
||||
|
||||
QWidget *additionalWidget() const;
|
||||
|
||||
|
@@ -127,6 +127,7 @@ public:
|
||||
Utils::EnvironmentModel *m_model;
|
||||
|
||||
QString m_baseEnvironmentText;
|
||||
EnvironmentWidget::OpenTerminalFunc m_openTerminalFunc;
|
||||
Utils::DetailsWidget *m_detailsContainer;
|
||||
QTreeView *m_environmentView;
|
||||
QPushButton *m_editButton;
|
||||
@@ -227,6 +228,7 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
|
||||
d->m_terminalButton = new QPushButton(this);
|
||||
d->m_terminalButton->setText(tr("Open &Terminal"));
|
||||
d->m_terminalButton->setToolTip(tr("Open a terminal with this environment set up."));
|
||||
d->m_terminalButton->setEnabled(type == TypeLocal);
|
||||
buttonLayout->addWidget(d->m_terminalButton);
|
||||
buttonLayout->addStretch();
|
||||
|
||||
@@ -251,7 +253,14 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
|
||||
connect(d->m_environmentView->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||
this, &EnvironmentWidget::environmentCurrentIndexChanged);
|
||||
connect(d->m_terminalButton, &QAbstractButton::clicked,
|
||||
this, &EnvironmentWidget::openTerminal);
|
||||
this, [this] {
|
||||
Utils::Environment env = d->m_model->baseEnvironment();
|
||||
env.modify(d->m_model->userChanges());
|
||||
if (d->m_openTerminalFunc)
|
||||
d->m_openTerminalFunc(env);
|
||||
else
|
||||
Core::FileUtils::openTerminal(QDir::currentPath(), env);
|
||||
});
|
||||
connect(d->m_detailsContainer, &Utils::DetailsWidget::linkActivated,
|
||||
this, &EnvironmentWidget::linkActivated);
|
||||
|
||||
@@ -303,6 +312,12 @@ void EnvironmentWidget::setUserChanges(const QList<Utils::EnvironmentItem> &list
|
||||
updateSummaryText();
|
||||
}
|
||||
|
||||
void EnvironmentWidget::setOpenTerminalFunc(const EnvironmentWidget::OpenTerminalFunc &func)
|
||||
{
|
||||
d->m_openTerminalFunc = func;
|
||||
d->m_terminalButton->setEnabled(bool(func));
|
||||
}
|
||||
|
||||
void EnvironmentWidget::updateSummaryText()
|
||||
{
|
||||
QList<Utils::EnvironmentItem> list = d->m_model->userChanges();
|
||||
@@ -450,13 +465,6 @@ void EnvironmentWidget::batchEditEnvironmentButtonClicked()
|
||||
d->m_model->setUserChanges(newChanges);
|
||||
}
|
||||
|
||||
void EnvironmentWidget::openTerminal()
|
||||
{
|
||||
Utils::Environment env = d->m_model->baseEnvironment();
|
||||
env.modify(d->m_model->userChanges());
|
||||
Core::FileUtils::openTerminal(QDir::currentPath(), env);
|
||||
}
|
||||
|
||||
void EnvironmentWidget::environmentCurrentIndexChanged(const QModelIndex ¤t)
|
||||
{
|
||||
if (current.isValid()) {
|
||||
|
@@ -59,6 +59,9 @@ public:
|
||||
QList<Utils::EnvironmentItem> userChanges() const;
|
||||
void setUserChanges(const QList<Utils::EnvironmentItem> &list);
|
||||
|
||||
using OpenTerminalFunc = std::function<void(const Utils::Environment &env)>;
|
||||
void setOpenTerminalFunc(const OpenTerminalFunc &func);
|
||||
|
||||
signals:
|
||||
void userChangesChanged();
|
||||
void detailsVisibleChanged(bool visible);
|
||||
@@ -71,7 +74,6 @@ private:
|
||||
void appendPathButtonClicked();
|
||||
void prependPathButtonClicked();
|
||||
void batchEditEnvironmentButtonClicked();
|
||||
void openTerminal();
|
||||
void environmentCurrentIndexChanged(const QModelIndex ¤t);
|
||||
void invalidateCurrentIndex();
|
||||
void updateSummaryText();
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <ssh/sshremoteprocessrunner.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/port.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -197,24 +198,7 @@ LinuxDevice::LinuxDevice()
|
||||
|
||||
if (Utils::HostOsInfo::isAnyUnixHost()) {
|
||||
addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) {
|
||||
DeviceProcess * const proc = device->createProcess(nullptr);
|
||||
QObject::connect(proc, &DeviceProcess::finished, [proc] {
|
||||
if (!proc->errorString().isEmpty()) {
|
||||
Core::MessageManager::write(tr("Error running remote shell: %1")
|
||||
.arg(proc->errorString()),
|
||||
Core::MessageManager::ModeSwitch);
|
||||
}
|
||||
proc->deleteLater();
|
||||
});
|
||||
QObject::connect(proc, &DeviceProcess::error, [proc] {
|
||||
Core::MessageManager::write(tr("Error starting remote shell."),
|
||||
Core::MessageManager::ModeSwitch);
|
||||
proc->deleteLater();
|
||||
});
|
||||
Runnable runnable;
|
||||
runnable.device = device;
|
||||
proc->setRunInTerminal(true);
|
||||
proc->start(runnable);
|
||||
device.staticCast<LinuxDevice>()->startRemoteShell(Utils::Environment());
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -284,6 +268,35 @@ bool LinuxDevice::supportsRSync() const
|
||||
return extraData("RemoteLinux.SupportsRSync").toBool();
|
||||
}
|
||||
|
||||
void LinuxDevice::startRemoteShell(const Utils::Environment &env) const
|
||||
{
|
||||
DeviceProcess * const proc = createProcess(nullptr);
|
||||
QObject::connect(proc, &DeviceProcess::finished, [proc] {
|
||||
if (!proc->errorString().isEmpty()) {
|
||||
Core::MessageManager::write(tr("Error running remote shell: %1")
|
||||
.arg(proc->errorString()),
|
||||
Core::MessageManager::ModeSwitch);
|
||||
}
|
||||
proc->deleteLater();
|
||||
});
|
||||
QObject::connect(proc, &DeviceProcess::error, [proc] {
|
||||
Core::MessageManager::write(tr("Error starting remote shell."),
|
||||
Core::MessageManager::ModeSwitch);
|
||||
proc->deleteLater();
|
||||
});
|
||||
Runnable runnable;
|
||||
runnable.device = sharedFromThis();
|
||||
runnable.environment = env;
|
||||
|
||||
// It seems we cannot pass an environment to OpenSSH dynamically
|
||||
// without specifying an executable.
|
||||
if (env.size() > 0)
|
||||
runnable.executable = "/bin/sh";
|
||||
|
||||
proc->setRunInTerminal(true);
|
||||
proc->start(runnable);
|
||||
}
|
||||
|
||||
|
||||
namespace Internal {
|
||||
|
||||
|
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace Utils { class Environment; }
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice
|
||||
@@ -62,6 +64,8 @@ public:
|
||||
void setSupportsRsync(bool supportsRsync);
|
||||
bool supportsRSync() const;
|
||||
|
||||
void startRemoteShell(const Utils::Environment &env) const;
|
||||
|
||||
protected:
|
||||
LinuxDevice();
|
||||
};
|
||||
|
@@ -99,7 +99,8 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
|
||||
if (!envString.isEmpty())
|
||||
fullCommandLine.append(envString);
|
||||
if (!runInTerminal())
|
||||
fullCommandLine.append(" exec ");
|
||||
fullCommandLine.append(" exec");
|
||||
fullCommandLine.append(' ');
|
||||
fullCommandLine.append(quote(runnable.executable));
|
||||
if (!runnable.commandLineArguments.isEmpty()) {
|
||||
fullCommandLine.append(QLatin1Char(' '));
|
||||
|
@@ -25,11 +25,15 @@
|
||||
|
||||
#include "remotelinuxenvironmentaspectwidget.h"
|
||||
|
||||
#include "linuxdevice.h"
|
||||
#include "remotelinuxrunconfiguration.h"
|
||||
#include "remotelinuxenvironmentreader.h"
|
||||
|
||||
#include <projectexplorer/target.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/environmentwidget.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QMessageBox>
|
||||
@@ -63,6 +67,20 @@ RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget
|
||||
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentFinished);
|
||||
connect(deviceEnvReader, &RemoteLinuxEnvironmentReader::error,
|
||||
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentError);
|
||||
|
||||
const EnvironmentWidget::OpenTerminalFunc openTerminalFunc
|
||||
= [target](const Utils::Environment &env) {
|
||||
IDevice::ConstPtr device = DeviceKitAspect::device(target->kit());
|
||||
if (!device) {
|
||||
QMessageBox::critical(Core::ICore::mainWindow(), tr("Cannot open terminal"),
|
||||
tr("Cannot open remote terminal: Current kit has no device."));
|
||||
return;
|
||||
}
|
||||
const auto linuxDevice = device.dynamicCast<const LinuxDevice>();
|
||||
QTC_ASSERT(linuxDevice, return);
|
||||
linuxDevice->startRemoteShell(env);
|
||||
};
|
||||
envWidget()->setOpenTerminalFunc(openTerminalFunc);
|
||||
}
|
||||
|
||||
RemoteLinuxEnvironmentAspect *RemoteLinuxEnvironmentAspectWidget::aspect() const
|
||||
|
Reference in New Issue
Block a user