Maemo: Finish implementing "remote mount" feature.

Disabled on Windows for now due to utfs-server not working there.

Reviewed-by: kh1
This commit is contained in:
ck
2010-07-26 16:07:28 +02:00
parent 7608604c5f
commit f580db954f
9 changed files with 209 additions and 40 deletions

View File

@@ -69,6 +69,7 @@ static const QLatin1String ProFileKey(".ProFile");
static const QLatin1String ExportedLocalDirsKey(".ExportedLocalDirs"); static const QLatin1String ExportedLocalDirsKey(".ExportedLocalDirs");
static const QLatin1String RemoteMountPointsKey(".RemoteMountPoints"); static const QLatin1String RemoteMountPointsKey(".RemoteMountPoints");
static const QLatin1String MountPortsKey(".MountPorts"); static const QLatin1String MountPortsKey(".MountPorts");
static const QLatin1String HostAddressFromDeviceKey(".HostAddressFromDevice");
} // namespace Internal } // namespace Internal
} // namespace Qt4ProjectManager } // namespace Qt4ProjectManager

View File

@@ -35,9 +35,6 @@ namespace Qt4ProjectManager {
namespace Internal { namespace Internal {
namespace { namespace {
const int LocalDirRow = 0;
const int RemoteMountPointRow = 1;
const int PortRow = 2;
const QLatin1String InvalidMountPoint("/"); const QLatin1String InvalidMountPoint("/");
} // anonymous namespace } // anonymous namespace
@@ -46,7 +43,7 @@ MaemoRemoteMountsModel::MountSpecification::MountSpecification(const QString &l,
bool MaemoRemoteMountsModel::MountSpecification::isValid() const bool MaemoRemoteMountsModel::MountSpecification::isValid() const
{ {
return remoteMountPoint == InvalidMountPoint; return remoteMountPoint != InvalidMountPoint;
} }
@@ -81,6 +78,23 @@ void MaemoRemoteMountsModel::removeMountSpecificationAt(int pos)
endRemoveRows(); endRemoveRows();
} }
void MaemoRemoteMountsModel::setLocalDir(int pos, const QString &localDir)
{
Q_ASSERT(pos >= 0 && pos < rowCount());
m_mountSpecs[pos].localDir = localDir;
const QModelIndex currentIndex = index(pos, LocalDirRow);
emit dataChanged(currentIndex, currentIndex);
}
bool MaemoRemoteMountsModel::hasValidMountSpecifications() const
{
foreach (const MountSpecification &m, m_mountSpecs) {
if (m.isValid())
return true;
}
return false;
}
QVariantMap MaemoRemoteMountsModel::toMap() const QVariantMap MaemoRemoteMountsModel::toMap() const
{ {
QVariantMap map; QVariantMap map;

View File

@@ -54,13 +54,19 @@ public:
explicit MaemoRemoteMountsModel(QObject *parent = 0); explicit MaemoRemoteMountsModel(QObject *parent = 0);
int mountSpecificationCount() const { return m_mountSpecs.count(); } int mountSpecificationCount() const { return m_mountSpecs.count(); }
MountSpecification mountSpecificationAt(int pos) const { return m_mountSpecs.at(pos); } MountSpecification mountSpecificationAt(int pos) const { return m_mountSpecs.at(pos); }
bool hasValidMountSpecifications() const;
void addMountSpecification(const QString &localDir); void addMountSpecification(const QString &localDir);
void removeMountSpecificationAt(int pos); void removeMountSpecificationAt(int pos);
void setLocalDir(int pos, const QString &localDir);
QVariantMap toMap() const; QVariantMap toMap() const;
void fromMap(const QVariantMap &map); void fromMap(const QVariantMap &map);
static const int LocalDirRow = 0;
static const int RemoteMountPointRow = 1;
static const int PortRow = 2;
private: private:
virtual int columnCount(const QModelIndex& = QModelIndex()) const; virtual int columnCount(const QModelIndex& = QModelIndex()) const;
virtual int rowCount(const QModelIndex& = QModelIndex()) const; virtual int rowCount(const QModelIndex& = QModelIndex()) const;

View File

@@ -55,6 +55,8 @@
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
namespace Internal { namespace Internal {
namespace { const QLatin1String DefaultHostAddress("192.168.2.14"); }
using namespace ProjectExplorer; using namespace ProjectExplorer;
MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent, MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
@@ -79,6 +81,7 @@ void MaemoRunConfiguration::init()
{ {
m_devConfigModel = new MaemoDeviceConfigListModel(this); m_devConfigModel = new MaemoDeviceConfigListModel(this);
m_remoteMounts = new MaemoRemoteMountsModel(this); m_remoteMounts = new MaemoRemoteMountsModel(this);
m_hostAddressFromDevice = DefaultHostAddress;
setDisplayName(QFileInfo(m_proFilePath).completeBaseName()); setDisplayName(QFileInfo(m_proFilePath).completeBaseName());
updateDeviceConfigurations(); updateDeviceConfigurations();
@@ -136,6 +139,7 @@ QVariantMap MaemoRunConfiguration::toMap() const
map.insert(ArgumentsKey, m_arguments); map.insert(ArgumentsKey, m_arguments);
const QDir dir = QDir(target()->project()->projectDirectory()); const QDir dir = QDir(target()->project()->projectDirectory());
map.insert(ProFileKey, dir.relativeFilePath(m_proFilePath)); map.insert(ProFileKey, dir.relativeFilePath(m_proFilePath));
map.insert(HostAddressFromDeviceKey, m_hostAddressFromDevice);
map.unite(m_devConfigModel->toMap()); map.unite(m_devConfigModel->toMap());
map.unite(m_remoteMounts->toMap()); map.unite(m_remoteMounts->toMap());
return map; return map;
@@ -149,6 +153,8 @@ bool MaemoRunConfiguration::fromMap(const QVariantMap &map)
m_arguments = map.value(ArgumentsKey).toStringList(); m_arguments = map.value(ArgumentsKey).toStringList();
const QDir dir = QDir(target()->project()->projectDirectory()); const QDir dir = QDir(target()->project()->projectDirectory());
m_proFilePath = dir.filePath(map.value(ProFileKey).toString()); m_proFilePath = dir.filePath(map.value(ProFileKey).toString());
m_hostAddressFromDevice = map.value(HostAddressFromDeviceKey,
DefaultHostAddress).toString();
m_devConfigModel->fromMap(map); m_devConfigModel->fromMap(map);
m_remoteMounts->fromMap(map); m_remoteMounts->fromMap(map);
@@ -192,8 +198,12 @@ MaemoDeployStep *MaemoRunConfiguration::deployStep() const
QString MaemoRunConfiguration::localHostAddressFromDevice() const QString MaemoRunConfiguration::localHostAddressFromDevice() const
{ {
// TODO: From user return m_hostAddressFromDevice;
return QLatin1String("192.168.2.14"); }
void MaemoRunConfiguration::setLocalHostAddressFromDevice(const QString &address)
{
m_hostAddressFromDevice = address;
} }
QString MaemoRunConfiguration::maddeRoot() const QString MaemoRunConfiguration::maddeRoot() const

View File

@@ -77,6 +77,7 @@ public:
MaemoDeployStep *deployStep() const; MaemoDeployStep *deployStep() const;
MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; } MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
QString localHostAddressFromDevice() const; QString localHostAddressFromDevice() const;
void setLocalHostAddressFromDevice(const QString &address);
const MaemoToolChain *toolchain() const; const MaemoToolChain *toolchain() const;
QString maddeRoot() const; QString maddeRoot() const;
@@ -115,6 +116,7 @@ private:
MaemoDeviceConfigListModel *m_devConfigModel; MaemoDeviceConfigListModel *m_devConfigModel;
MaemoRemoteMountsModel *m_remoteMounts; MaemoRemoteMountsModel *m_remoteMounts;
QStringList m_arguments; QStringList m_arguments;
QString m_hostAddressFromDevice;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -36,20 +36,21 @@
#include "maemodeviceconfiglistmodel.h" #include "maemodeviceconfiglistmodel.h"
#include "maemomanager.h" #include "maemomanager.h"
#include "maemoremotemountsmodel.h"
#include "maemorunconfiguration.h" #include "maemorunconfiguration.h"
#include "maemosettingspage.h" #include "maemosettingspage.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <QtGui/QComboBox> #include <QtGui/QComboBox>
#include <QtGui/QCheckBox> #include <QtGui/QFileDialog>
#include <QtGui/QDesktopServices>
#include <QtGui/QFormLayout> #include <QtGui/QFormLayout>
#include <QtGui/QFrame> #include <QtGui/QGroupBox>
#include <QtGui/QHBoxLayout> #include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
#include <QtGui/QRadioButton> #include <QtGui/QTableView>
#include <QtGui/QToolButton> #include <QtGui/QToolButton>
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
@@ -59,12 +60,14 @@ MaemoRunConfigurationWidget::MaemoRunConfigurationWidget(
MaemoRunConfiguration *runConfiguration, QWidget *parent) MaemoRunConfiguration *runConfiguration, QWidget *parent)
: QWidget(parent), m_runConfiguration(runConfiguration) : QWidget(parent), m_runConfiguration(runConfiguration)
{ {
QFormLayout *mainLayout = new QFormLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
setLayout(mainLayout); setLayout(mainLayout);
mainLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter); QFormLayout *formLayout = new QFormLayout;
mainLayout->addLayout(formLayout);
formLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_configNameLineEdit = new QLineEdit(m_runConfiguration->displayName()); m_configNameLineEdit = new QLineEdit(m_runConfiguration->displayName());
mainLayout->addRow(tr("Run configuration name:"), m_configNameLineEdit); formLayout->addRow(tr("Run configuration name:"), m_configNameLineEdit);
QWidget *devConfWidget = new QWidget; QWidget *devConfWidget = new QWidget;
QHBoxLayout *devConfLayout = new QHBoxLayout(devConfWidget); QHBoxLayout *devConfLayout = new QHBoxLayout(devConfWidget);
@@ -83,13 +86,53 @@ MaemoRunConfigurationWidget::MaemoRunConfigurationWidget(
debuggerConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); debuggerConfLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
devConfLayout->addWidget(debuggerConfLabel); devConfLayout->addWidget(debuggerConfLabel);
mainLayout->addRow(new QLabel(tr("Device configuration:")), devConfWidget); formLayout->addRow(new QLabel(tr("Device configuration:")), devConfWidget);
m_executableLabel = new QLabel(m_runConfiguration->localExecutableFilePath()); m_executableLabel = new QLabel(m_runConfiguration->localExecutableFilePath());
mainLayout->addRow(tr("Executable:"), m_executableLabel); formLayout->addRow(tr("Executable:"), m_executableLabel);
m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" ")); m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" "));
mainLayout->addRow(tr("Arguments:"), m_argsLineEdit); formLayout->addRow(tr("Arguments:"), m_argsLineEdit);
mainLayout->addSpacing(20);
QGroupBox *mountViewBox = new QGroupBox;
#ifndef Q_OS_WIN
mainLayout->addWidget(mountViewBox);
#endif
mountViewBox->setTitle(tr("Local Directories to mount from device"));
QVBoxLayout *mountViewLayout = new QVBoxLayout(mountViewBox);
QHBoxLayout *hostAddressLayout = new QHBoxLayout;
mountViewLayout->addLayout(hostAddressLayout);
QLabel *hostNameLabel
= new QLabel(tr("This host's address from the device:"));
m_hostAddressLineEdit = new QLineEdit;
m_hostAddressLineEdit->setText(m_runConfiguration->localHostAddressFromDevice());
connect(m_hostAddressLineEdit, SIGNAL(editingFinished()), this,
SLOT(handleHostAddressChanged()));
hostAddressLayout->addWidget(hostNameLabel);
hostAddressLayout->addWidget(m_hostAddressLineEdit);
hostAddressLayout->addStretch(1);
QHBoxLayout *tableLayout = new QHBoxLayout;
mountViewLayout->addLayout(tableLayout);
m_mountView = new QTableView;
m_mountView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
m_mountView->setSelectionBehavior(QTableView::SelectRows);
m_mountView->setModel(m_runConfiguration->remoteMounts());
tableLayout->addWidget(m_mountView);
QVBoxLayout *mountViewButtonsLayout = new QVBoxLayout;
tableLayout->addLayout(mountViewButtonsLayout);
QToolButton *addMountButton = new QToolButton;
QIcon plusIcon;
plusIcon.addFile(QLatin1String(":/core/images/plus.png"));
addMountButton->setIcon(plusIcon);
mountViewButtonsLayout->addWidget(addMountButton);
m_removeMountButton = new QToolButton;
QIcon minusIcon;
minusIcon.addFile(QLatin1String(":/core/images/minus.png"));
m_removeMountButton->setIcon(minusIcon);
mountViewButtonsLayout->addWidget(m_removeMountButton);
mountViewButtonsLayout->addStretch(1);
handleCurrentDeviceConfigChanged(); handleCurrentDeviceConfigChanged();
enableOrDisableRemoveButton();
connect(m_configNameLineEdit, SIGNAL(textEdited(QString)), this, connect(m_configNameLineEdit, SIGNAL(textEdited(QString)), this,
SLOT(configNameEdited(QString))); SLOT(configNameEdited(QString)));
connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this, connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this,
@@ -104,6 +147,13 @@ MaemoRunConfigurationWidget::MaemoRunConfigurationWidget(
SLOT(showSettingsDialog(QString))); SLOT(showSettingsDialog(QString)));
connect(debuggerConfLabel, SIGNAL(linkActivated(QString)), this, connect(debuggerConfLabel, SIGNAL(linkActivated(QString)), this,
SLOT(showSettingsDialog(QString))); SLOT(showSettingsDialog(QString)));
connect(addMountButton, SIGNAL(clicked()), this, SLOT(addMount()));
connect(m_removeMountButton, SIGNAL(clicked()), this, SLOT(removeMount()));
connect(m_mountView, SIGNAL(doubleClicked(QModelIndex)), this,
SLOT(changeLocalMountDir(QModelIndex)));
connect(m_mountView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this,
SLOT(enableOrDisableRemoveButton()));
} }
void MaemoRunConfigurationWidget::configNameEdited(const QString &text) void MaemoRunConfigurationWidget::configNameEdited(const QString &text)
@@ -143,5 +193,54 @@ void MaemoRunConfigurationWidget::setCurrentDeviceConfig(int index)
m_runConfiguration->deviceConfigModel()->setCurrentIndex(index); m_runConfiguration->deviceConfigModel()->setCurrentIndex(index);
} }
void MaemoRunConfigurationWidget::enableOrDisableRemoveButton()
{
const QModelIndexList selectedRows
= m_mountView->selectionModel()->selectedRows();
m_removeMountButton->setEnabled(!selectedRows.isEmpty());
}
void MaemoRunConfigurationWidget::addMount()
{
const QString localDir = QFileDialog::getExistingDirectory(this,
tr("Choose directory to mount"));
if (!localDir.isEmpty()) {
MaemoRemoteMountsModel * const mountsModel
= m_runConfiguration->remoteMounts();
mountsModel->addMountSpecification(localDir);
m_mountView->edit(mountsModel->index(mountsModel->mountSpecificationCount() - 1,
mountsModel->RemoteMountPointRow));
}
}
void MaemoRunConfigurationWidget::removeMount()
{
const QModelIndexList selectedRows
= m_mountView->selectionModel()->selectedRows();
if (!selectedRows.isEmpty()) {
m_runConfiguration->remoteMounts()
->removeMountSpecificationAt(selectedRows.first().row());
}
}
void MaemoRunConfigurationWidget::changeLocalMountDir(const QModelIndex &index)
{
if (index.column() == MaemoRemoteMountsModel::LocalDirRow) {
MaemoRemoteMountsModel * const mountsModel
= m_runConfiguration->remoteMounts();
const QString oldDir
= mountsModel->mountSpecificationAt(index.row()).localDir;
const QString localDir = QFileDialog::getExistingDirectory(this,
tr("Choose directory to mount"), oldDir);
if (!localDir.isEmpty())
mountsModel->setLocalDir(index.row(), localDir);
}
}
void MaemoRunConfigurationWidget::handleHostAddressChanged()
{
m_runConfiguration->setLocalHostAddressFromDevice(m_hostAddressLineEdit->text());
}
} // namespace Internal } // namespace Internal
} // namespace Qt4ProjectManager } // namespace Qt4ProjectManager

View File

@@ -41,6 +41,9 @@ QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
class QModelIndex;
class QTableView;
class QToolButton;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
@@ -62,13 +65,20 @@ private slots:
void updateTargetInformation(); void updateTargetInformation();
void handleCurrentDeviceConfigChanged(); void handleCurrentDeviceConfigChanged();
void setCurrentDeviceConfig(int index); void setCurrentDeviceConfig(int index);
void addMount();
void removeMount();
void changeLocalMountDir(const QModelIndex &index);
void enableOrDisableRemoveButton();
void handleHostAddressChanged();
private: private:
QLineEdit *m_configNameLineEdit; QLineEdit *m_configNameLineEdit;
QLineEdit *m_argsLineEdit; QLineEdit *m_argsLineEdit;
QLabel *m_executableLabel; QLabel *m_executableLabel;
QLabel *m_debuggerLabel;
QComboBox *m_devConfBox; QComboBox *m_devConfBox;
QLineEdit *m_hostAddressLineEdit;
QTableView *m_mountView;
QToolButton *m_removeMountButton;
MaemoRunConfiguration *m_runConfiguration; MaemoRunConfiguration *m_runConfiguration;
}; };

View File

@@ -143,9 +143,12 @@ void MaemoSshRunner::cleanup(bool initialCleanup)
const MaemoRemoteMountsModel * const remoteMounts const MaemoRemoteMountsModel * const remoteMounts
= m_runConfig->remoteMounts(); = m_runConfig->remoteMounts();
for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) { for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) {
remoteCall += QString::fromLocal8Bit("%1 umount %2;") const MaemoRemoteMountsModel::MountSpecification &mountSpec
.arg(MaemoGlobal::remoteSudo(), = remoteMounts->mountSpecificationAt(i);
remoteMounts->mountSpecificationAt(i).remoteMountPoint); if (mountSpec.isValid()) {
remoteCall += QString::fromLocal8Bit("%1 umount %2;")
.arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint);
}
} }
remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon. remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon.
@@ -177,7 +180,7 @@ void MaemoSshRunner::handleInitialCleanupFinished(int exitStatus)
if (exitStatus != SshRemoteProcess::ExitedNormally) { if (exitStatus != SshRemoteProcess::ExitedNormally) {
emit error(tr("Initial cleanup failed: %1") emit error(tr("Initial cleanup failed: %1")
.arg(m_initialCleaner->errorString())); .arg(m_initialCleaner->errorString()));
} else if (m_runConfig->remoteMounts()->mountSpecificationCount() != 0) { } else if (m_runConfig->remoteMounts()->hasValidMountSpecifications()) {
deployUtfsClient(); deployUtfsClient();
} else { } else {
emit readyForExecution(); emit readyForExecution();
@@ -215,7 +218,7 @@ void MaemoSshRunner::handleUploaderInitialized()
Q_ASSERT_X(toolChain, Q_FUNC_INFO, Q_ASSERT_X(toolChain, Q_FUNC_INFO,
"Impossible: Maemo run configuration has no Maemo Toolchain."); "Impossible: Maemo run configuration has no Maemo Toolchain.");
const QString localFile const QString localFile
= toolChain->maddeRoot() + QLatin1String("/madlib/utfs-client"); = toolChain->maddeRoot() + QLatin1String("/madlib/armel/utfs-client");
m_uploadJobId m_uploadJobId
= m_utfsClientUploader->uploadFile(localFile, utfsClientOnDevice(), = m_utfsClientUploader->uploadFile(localFile, utfsClientOnDevice(),
SftpOverwriteExisting); SftpOverwriteExisting);
@@ -247,19 +250,30 @@ void MaemoSshRunner::mount()
{ {
const MaemoRemoteMountsModel * const remoteMounts const MaemoRemoteMountsModel * const remoteMounts
= m_runConfig->remoteMounts(); = m_runConfig->remoteMounts();
QString remoteCall(QLatin1String(":")); const QString chmodFuse
= MaemoGlobal::remoteSudo() + QLatin1String(" chmod a+r+w /dev/fuse");
const QString chmodUtfsClient
= QLatin1String("chmod a+x ") + utfsClientOnDevice();
const QLatin1String andOp(" && ");
QString remoteCall = chmodFuse + andOp + chmodUtfsClient;
for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) { for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) {
const MaemoRemoteMountsModel::MountSpecification &mountSpec const MaemoRemoteMountsModel::MountSpecification &mountSpec
= remoteMounts->mountSpecificationAt(i); = remoteMounts->mountSpecificationAt(i);
if (!mountSpec.isValid())
continue;
QProcess * const utfsServerProc = new QProcess(this); QProcess * const utfsServerProc = new QProcess(this);
connect(utfsServerProc, SIGNAL(readyReadStandardError()), this,
SLOT(handleUtfsServerErrorOutput()));
const QString port = QString::number(mountSpec.port); const QString port = QString::number(mountSpec.port);
const QString localSecretOpt = QLatin1String("-l"); const QString localSecretOpt = QLatin1String("-l");
const QString remoteSecretOpt = QLatin1String("-r"); const QString remoteSecretOpt = QLatin1String("-r");
const QStringList utfsServerArgs = QStringList() << localSecretOpt const QStringList utfsServerArgs = QStringList() << localSecretOpt
<< port << remoteSecretOpt << port << QLatin1String("-b") << port; << port << remoteSecretOpt << port << QLatin1String("-b") << port
<< mountSpec.localDir;
utfsServerProc->start(utfsServer(), utfsServerArgs); utfsServerProc->start(utfsServer(), utfsServerArgs);
if (!utfsServerProc->waitForStarted()) { if (!utfsServerProc->waitForStarted()) {
delete utfsServerProc;
emit error(tr("Could not start UTFS server: %1") emit error(tr("Could not start UTFS server: %1")
.arg(utfsServerProc->errorString())); .arg(utfsServerProc->errorString()));
return; return;
@@ -267,40 +281,47 @@ void MaemoSshRunner::mount()
m_utfsServers << utfsServerProc; m_utfsServers << utfsServerProc;
const QString mkdir = QString::fromLocal8Bit("%1 mkdir -p %2") const QString mkdir = QString::fromLocal8Bit("%1 mkdir -p %2")
.arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint); .arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint);
const QString chmod = QString::fromLocal8Bit("%1 chmod a+r+w+x %2")
.arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint);
const QString utfsClient const QString utfsClient
= QString::fromLocal8Bit("%1 -l %2 -r %2 -c %3:%2 %4") = QString::fromLocal8Bit("%1 -l %2 -r %2 -c %3:%2 %4")
.arg(utfsClientOnDevice()).arg(port) .arg(utfsClientOnDevice()).arg(port)
.arg(m_runConfig->localHostAddressFromDevice()) .arg(m_runConfig->localHostAddressFromDevice())
.arg(mountSpec.remoteMountPoint); .arg(mountSpec.remoteMountPoint);
const QLatin1String andOp(" && "); remoteCall += andOp + mkdir + andOp + chmod + andOp + utfsClient;
remoteCall += andOp + mkdir + andOp + utfsClient;
} }
m_mountProcess = m_connection->createRemoteProcess(remoteCall.toUtf8()); m_mountProcess = m_connection->createRemoteProcess(remoteCall.toUtf8());
connect(m_mountProcess.data(), SIGNAL(started()), this,
SLOT(handleMountProcessStarted()));
connect(m_mountProcess.data(), SIGNAL(closed(int)), this, connect(m_mountProcess.data(), SIGNAL(closed(int)), this,
SLOT(handleRemoteProcessFinished(int))); SLOT(handleMountProcessFinished(int)));
connect(m_mountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)),
this, SIGNAL(remoteErrorOutput(QByteArray)));
m_mountProcess->start(); m_mountProcess->start();
} }
void MaemoSshRunner::handleMountProcessStarted()
{
// TODO: Do we get "finished" from utfs-client when it goes into background?
// If so, remnove this slot; readyForExecution() should be emitted from
// handleRemoteProcessFinished() in that case.
if (!m_stop)
emit readyForExecution();
}
void MaemoSshRunner::handleMountProcessFinished(int exitStatus) void MaemoSshRunner::handleMountProcessFinished(int exitStatus)
{ {
if (m_stop) if (m_stop)
return; return;
if (exitStatus != SshRemoteProcess::ExitedNormally) { switch (exitStatus) {
case SshRemoteProcess::FailedToStart:
emit error(tr("Could not execute mount request."));
break;
case SshRemoteProcess::KilledBySignal:
emit error(tr("Failure running UTFS client: %1") emit error(tr("Failure running UTFS client: %1")
.arg(m_mountProcess->errorString())); .arg(m_mountProcess->errorString()));
break;
case SshRemoteProcess::ExitedNormally:
if (m_mountProcess->exitCode() == 0) {
emit readyForExecution();
} else {
emit error(tr("Could not execute mount request."));
}
break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO,
"Impossible SshRemoteProcess exit status.");
} }
} }
@@ -338,6 +359,7 @@ void MaemoSshRunner::handleRemoteProcessFinished(int exitStatus)
emit error(tr("Error running remote process: %1") emit error(tr("Error running remote process: %1")
.arg(m_runner->errorString())); .arg(m_runner->errorString()));
} }
cleanup(false);
} }
QString MaemoSshRunner::utfsClientOnDevice() const QString MaemoSshRunner::utfsClientOnDevice() const
@@ -355,6 +377,11 @@ QString MaemoSshRunner::utfsServer() const
return toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server"); return toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server");
} }
void MaemoSshRunner::handleUtfsServerErrorOutput()
{
emit remoteErrorOutput(qobject_cast<QProcess *>(sender())->readAllStandardError());
}
} // namespace Internal } // namespace Internal
} // namespace Qt4ProjectManager } // namespace Qt4ProjectManager

View File

@@ -89,8 +89,8 @@ private slots:
void handleUploaderInitialized(); void handleUploaderInitialized();
void handleUploaderInitializationFailed(const QString &reason); void handleUploaderInitializationFailed(const QString &reason);
void handleUploadFinished(Core::SftpJobId jobId, const QString &error); void handleUploadFinished(Core::SftpJobId jobId, const QString &error);
void handleMountProcessStarted();
void handleMountProcessFinished(int exitStatus); void handleMountProcessFinished(int exitStatus);
void handleUtfsServerErrorOutput();
private: private:
void cleanup(bool initialCleanup); void cleanup(bool initialCleanup);