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);
|
explicit EnvironmentAspectWidget(EnvironmentAspect *aspect, QWidget *additionalWidget = nullptr);
|
||||||
|
|
||||||
virtual EnvironmentAspect *aspect() const;
|
virtual EnvironmentAspect *aspect() const;
|
||||||
|
EnvironmentWidget *envWidget() const { return m_environmentWidget; }
|
||||||
|
|
||||||
QWidget *additionalWidget() const;
|
QWidget *additionalWidget() const;
|
||||||
|
|
||||||
|
@@ -127,6 +127,7 @@ public:
|
|||||||
Utils::EnvironmentModel *m_model;
|
Utils::EnvironmentModel *m_model;
|
||||||
|
|
||||||
QString m_baseEnvironmentText;
|
QString m_baseEnvironmentText;
|
||||||
|
EnvironmentWidget::OpenTerminalFunc m_openTerminalFunc;
|
||||||
Utils::DetailsWidget *m_detailsContainer;
|
Utils::DetailsWidget *m_detailsContainer;
|
||||||
QTreeView *m_environmentView;
|
QTreeView *m_environmentView;
|
||||||
QPushButton *m_editButton;
|
QPushButton *m_editButton;
|
||||||
@@ -227,6 +228,7 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
|
|||||||
d->m_terminalButton = new QPushButton(this);
|
d->m_terminalButton = new QPushButton(this);
|
||||||
d->m_terminalButton->setText(tr("Open &Terminal"));
|
d->m_terminalButton->setText(tr("Open &Terminal"));
|
||||||
d->m_terminalButton->setToolTip(tr("Open a terminal with this environment set up."));
|
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->addWidget(d->m_terminalButton);
|
||||||
buttonLayout->addStretch();
|
buttonLayout->addStretch();
|
||||||
|
|
||||||
@@ -251,7 +253,14 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
|
|||||||
connect(d->m_environmentView->selectionModel(), &QItemSelectionModel::currentChanged,
|
connect(d->m_environmentView->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||||
this, &EnvironmentWidget::environmentCurrentIndexChanged);
|
this, &EnvironmentWidget::environmentCurrentIndexChanged);
|
||||||
connect(d->m_terminalButton, &QAbstractButton::clicked,
|
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,
|
connect(d->m_detailsContainer, &Utils::DetailsWidget::linkActivated,
|
||||||
this, &EnvironmentWidget::linkActivated);
|
this, &EnvironmentWidget::linkActivated);
|
||||||
|
|
||||||
@@ -303,6 +312,12 @@ void EnvironmentWidget::setUserChanges(const QList<Utils::EnvironmentItem> &list
|
|||||||
updateSummaryText();
|
updateSummaryText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnvironmentWidget::setOpenTerminalFunc(const EnvironmentWidget::OpenTerminalFunc &func)
|
||||||
|
{
|
||||||
|
d->m_openTerminalFunc = func;
|
||||||
|
d->m_terminalButton->setEnabled(bool(func));
|
||||||
|
}
|
||||||
|
|
||||||
void EnvironmentWidget::updateSummaryText()
|
void EnvironmentWidget::updateSummaryText()
|
||||||
{
|
{
|
||||||
QList<Utils::EnvironmentItem> list = d->m_model->userChanges();
|
QList<Utils::EnvironmentItem> list = d->m_model->userChanges();
|
||||||
@@ -450,13 +465,6 @@ void EnvironmentWidget::batchEditEnvironmentButtonClicked()
|
|||||||
d->m_model->setUserChanges(newChanges);
|
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)
|
void EnvironmentWidget::environmentCurrentIndexChanged(const QModelIndex ¤t)
|
||||||
{
|
{
|
||||||
if (current.isValid()) {
|
if (current.isValid()) {
|
||||||
|
@@ -59,6 +59,9 @@ public:
|
|||||||
QList<Utils::EnvironmentItem> userChanges() const;
|
QList<Utils::EnvironmentItem> userChanges() const;
|
||||||
void setUserChanges(const QList<Utils::EnvironmentItem> &list);
|
void setUserChanges(const QList<Utils::EnvironmentItem> &list);
|
||||||
|
|
||||||
|
using OpenTerminalFunc = std::function<void(const Utils::Environment &env)>;
|
||||||
|
void setOpenTerminalFunc(const OpenTerminalFunc &func);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void userChangesChanged();
|
void userChangesChanged();
|
||||||
void detailsVisibleChanged(bool visible);
|
void detailsVisibleChanged(bool visible);
|
||||||
@@ -71,7 +74,6 @@ private:
|
|||||||
void appendPathButtonClicked();
|
void appendPathButtonClicked();
|
||||||
void prependPathButtonClicked();
|
void prependPathButtonClicked();
|
||||||
void batchEditEnvironmentButtonClicked();
|
void batchEditEnvironmentButtonClicked();
|
||||||
void openTerminal();
|
|
||||||
void environmentCurrentIndexChanged(const QModelIndex ¤t);
|
void environmentCurrentIndexChanged(const QModelIndex ¤t);
|
||||||
void invalidateCurrentIndex();
|
void invalidateCurrentIndex();
|
||||||
void updateSummaryText();
|
void updateSummaryText();
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include <ssh/sshremoteprocessrunner.h>
|
#include <ssh/sshremoteprocessrunner.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/environment.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/port.h>
|
#include <utils/port.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -197,24 +198,7 @@ LinuxDevice::LinuxDevice()
|
|||||||
|
|
||||||
if (Utils::HostOsInfo::isAnyUnixHost()) {
|
if (Utils::HostOsInfo::isAnyUnixHost()) {
|
||||||
addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) {
|
addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) {
|
||||||
DeviceProcess * const proc = device->createProcess(nullptr);
|
device.staticCast<LinuxDevice>()->startRemoteShell(Utils::Environment());
|
||||||
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);
|
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,6 +268,35 @@ bool LinuxDevice::supportsRSync() const
|
|||||||
return extraData("RemoteLinux.SupportsRSync").toBool();
|
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 {
|
namespace Internal {
|
||||||
|
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
namespace Utils { class Environment; }
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice
|
class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice
|
||||||
@@ -62,6 +64,8 @@ public:
|
|||||||
void setSupportsRsync(bool supportsRsync);
|
void setSupportsRsync(bool supportsRsync);
|
||||||
bool supportsRSync() const;
|
bool supportsRSync() const;
|
||||||
|
|
||||||
|
void startRemoteShell(const Utils::Environment &env) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LinuxDevice();
|
LinuxDevice();
|
||||||
};
|
};
|
||||||
|
@@ -99,7 +99,8 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
|
|||||||
if (!envString.isEmpty())
|
if (!envString.isEmpty())
|
||||||
fullCommandLine.append(envString);
|
fullCommandLine.append(envString);
|
||||||
if (!runInTerminal())
|
if (!runInTerminal())
|
||||||
fullCommandLine.append(" exec ");
|
fullCommandLine.append(" exec");
|
||||||
|
fullCommandLine.append(' ');
|
||||||
fullCommandLine.append(quote(runnable.executable));
|
fullCommandLine.append(quote(runnable.executable));
|
||||||
if (!runnable.commandLineArguments.isEmpty()) {
|
if (!runnable.commandLineArguments.isEmpty()) {
|
||||||
fullCommandLine.append(QLatin1Char(' '));
|
fullCommandLine.append(QLatin1Char(' '));
|
||||||
|
@@ -25,11 +25,15 @@
|
|||||||
|
|
||||||
#include "remotelinuxenvironmentaspectwidget.h"
|
#include "remotelinuxenvironmentaspectwidget.h"
|
||||||
|
|
||||||
|
#include "linuxdevice.h"
|
||||||
#include "remotelinuxrunconfiguration.h"
|
#include "remotelinuxrunconfiguration.h"
|
||||||
#include "remotelinuxenvironmentreader.h"
|
#include "remotelinuxenvironmentreader.h"
|
||||||
|
|
||||||
#include <projectexplorer/target.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <projectexplorer/environmentwidget.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@@ -63,6 +67,20 @@ RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget
|
|||||||
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentFinished);
|
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentFinished);
|
||||||
connect(deviceEnvReader, &RemoteLinuxEnvironmentReader::error,
|
connect(deviceEnvReader, &RemoteLinuxEnvironmentReader::error,
|
||||||
this, &RemoteLinuxEnvironmentAspectWidget::fetchEnvironmentError);
|
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
|
RemoteLinuxEnvironmentAspect *RemoteLinuxEnvironmentAspectWidget::aspect() const
|
||||||
|
Reference in New Issue
Block a user