forked from qt-creator/qt-creator
SSH: Add download capability to SftpFileSystemModel.
Change-Id: I156fa2ecc179f7f9a75ea0c1357b7e6881f5740f Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -94,6 +94,7 @@ public:
|
||||
SftpFileNode *rootNode;
|
||||
SftpJobId statJobId;
|
||||
DirNodeHash lsOps;
|
||||
QList<SftpJobId> externalJobs;
|
||||
};
|
||||
} // namespace Internal
|
||||
|
||||
@@ -143,6 +144,19 @@ QString SftpFileSystemModel::rootDirectory() const
|
||||
return d->rootDirectory;
|
||||
}
|
||||
|
||||
SftpJobId SftpFileSystemModel::downloadFile(const QModelIndex &index, const QString &targetFilePath)
|
||||
{
|
||||
QTC_ASSERT(d->rootNode, return SftpInvalidJob);
|
||||
const SftpFileNode * const fileNode = indexToFileNode(index);
|
||||
QTC_ASSERT(fileNode, return SftpInvalidJob);
|
||||
QTC_ASSERT(fileNode->fileInfo.type == FileTypeRegular, return SftpInvalidJob);
|
||||
const SftpJobId jobId = d->sftpChannel->downloadFile(fileNode->path, targetFilePath,
|
||||
SftpOverwriteExisting);
|
||||
if (jobId != SftpInvalidJob)
|
||||
d->externalJobs << jobId;
|
||||
return jobId;
|
||||
}
|
||||
|
||||
int SftpFileSystemModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
@@ -344,21 +358,29 @@ void SftpFileSystemModel::handleFileInfo(SftpJobId jobId, const QList<SftpFileIn
|
||||
|
||||
void SftpFileSystemModel::handleSftpJobFinished(SftpJobId jobId, const QString &errorMessage)
|
||||
{
|
||||
QString path;
|
||||
if (jobId == d->statJobId) {
|
||||
d->statJobId = SftpInvalidJob;
|
||||
path = rootDirectory();
|
||||
} else {
|
||||
DirNodeHash::Iterator it = d->lsOps.find(jobId);
|
||||
QTC_ASSERT(it != d->lsOps.end(), return);
|
||||
QTC_CHECK(it.value()->lsState == SftpDirNode::LsRunning);
|
||||
it.value()->lsState = SftpDirNode::LsFinished;
|
||||
path = it.value()->path;
|
||||
d->lsOps.erase(it);
|
||||
if (!errorMessage.isEmpty())
|
||||
emit sftpOperationFailed(tr("Error getting 'stat' info about '%1': %2")
|
||||
.arg(rootDirectory(), errorMessage));
|
||||
return;
|
||||
}
|
||||
|
||||
DirNodeHash::Iterator it = d->lsOps.find(jobId);
|
||||
if (it != d->lsOps.end()) {
|
||||
QTC_CHECK(it.value()->lsState == SftpDirNode::LsRunning);
|
||||
it.value()->lsState = SftpDirNode::LsFinished;
|
||||
if (!errorMessage.isEmpty())
|
||||
emit sftpOperationFailed(tr("Error reading '%1': %2").arg(path, errorMessage));
|
||||
emit sftpOperationFailed(tr("Error listing contents of directory '%1': %2")
|
||||
.arg(it.value()->path, errorMessage));
|
||||
d->lsOps.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
const int jobIndex = d->externalJobs.indexOf(jobId);
|
||||
QTC_ASSERT(jobIndex != -1, return);
|
||||
d->externalJobs.removeAt(jobIndex);
|
||||
emit sftpOperationFinished(jobId, errorMessage);
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
@@ -63,6 +63,8 @@ public:
|
||||
void setRootDirectory(const QString &path); // Default is "/".
|
||||
QString rootDirectory() const;
|
||||
|
||||
SftpJobId downloadFile(const QModelIndex &index, const QString &targetFilePath);
|
||||
|
||||
signals:
|
||||
/*
|
||||
* E.g. "Permission denied". Note that this can happen without direct user intervention,
|
||||
@@ -77,6 +79,9 @@ signals:
|
||||
*/
|
||||
void connectionError(const QString &errorMessage);
|
||||
|
||||
// Success <=> error.isEmpty().
|
||||
void sftpOperationFinished(Utils::SftpJobId, const QString &error);
|
||||
|
||||
private slots:
|
||||
void handleSshConnectionEstablished();
|
||||
void handleSshConnectionFailure();
|
||||
|
||||
@@ -38,7 +38,11 @@
|
||||
#include <utils/ssh/sshconnection.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QModelIndexList>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QString>
|
||||
|
||||
using namespace Utils;
|
||||
@@ -47,6 +51,7 @@ SftpFsWindow::SftpFsWindow(QWidget *parent) : QDialog(parent), m_ui(new Ui::Wind
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
connect(m_ui->connectButton, SIGNAL(clicked()), SLOT(connectToHost()));
|
||||
connect(m_ui->downloadButton, SIGNAL(clicked()), SLOT(downloadFile()));
|
||||
}
|
||||
|
||||
SftpFsWindow::~SftpFsWindow()
|
||||
@@ -64,19 +69,49 @@ void SftpFsWindow::connectToHost()
|
||||
sshParams.password = m_ui->passwordLineEdit->text();
|
||||
sshParams.port = m_ui->portSpinBox->value();
|
||||
sshParams.timeout = 10;
|
||||
SftpFileSystemModel * const fsModel = new SftpFileSystemModel(this);
|
||||
m_fsModel = new SftpFileSystemModel(this);
|
||||
if (m_ui->useModelTesterCheckBox->isChecked())
|
||||
new ModelTest(fsModel, this);
|
||||
connect(fsModel, SIGNAL(sftpOperationFailed(QString)),
|
||||
new ModelTest(m_fsModel, this);
|
||||
connect(m_fsModel, SIGNAL(sftpOperationFailed(QString)),
|
||||
SLOT(handleSftpOperationFailed(QString)));
|
||||
connect(fsModel, SIGNAL(connectionError(QString)), SLOT(handleConnectionError(QString)));
|
||||
fsModel->setSshConnection(sshParams);
|
||||
m_ui->fsView->setModel(fsModel);
|
||||
connect(m_fsModel, SIGNAL(connectionError(QString)), SLOT(handleConnectionError(QString)));
|
||||
connect(m_fsModel, SIGNAL(sftpOperationFinished(Utils::SftpJobId,QString)),
|
||||
SLOT(handleSftpOperationFinished(Utils::SftpJobId,QString)));
|
||||
m_fsModel->setSshConnection(sshParams);
|
||||
m_ui->fsView->setModel(m_fsModel);
|
||||
}
|
||||
|
||||
void SftpFsWindow::downloadFile()
|
||||
{
|
||||
const QModelIndexList selectedIndexes = m_ui->fsView->selectionModel()->selectedIndexes();
|
||||
if (selectedIndexes.count() != 2)
|
||||
return;
|
||||
const QString targetFilePath = QFileDialog::getSaveFileName(this, tr("Choose target file"),
|
||||
QDir::tempPath());
|
||||
if (targetFilePath.isEmpty())
|
||||
return;
|
||||
const SftpJobId jobId = m_fsModel->downloadFile(selectedIndexes.at(1), targetFilePath);
|
||||
QString message;
|
||||
if (jobId == SftpInvalidJob)
|
||||
message = tr("Download failed.");
|
||||
else
|
||||
message = tr("Queuing download operation %1.").arg(jobId);
|
||||
m_ui->outputTextEdit->appendPlainText(message);
|
||||
}
|
||||
|
||||
void SftpFsWindow::handleSftpOperationFailed(const QString &errorMessage)
|
||||
{
|
||||
qDebug("%s: %s", Q_FUNC_INFO, qPrintable(errorMessage));
|
||||
m_ui->outputTextEdit->appendPlainText(errorMessage);
|
||||
}
|
||||
|
||||
void SftpFsWindow::handleSftpOperationFinished(SftpJobId jobId, const QString &error)
|
||||
{
|
||||
QString message;
|
||||
if (error.isEmpty())
|
||||
message = tr("Operation %1 finished successfully.").arg(jobId);
|
||||
else
|
||||
message = tr("Operation %1 failed: %2.").arg(jobId).arg(error);
|
||||
m_ui->outputTextEdit->appendPlainText(message);
|
||||
}
|
||||
|
||||
void SftpFsWindow::handleConnectionError(const QString &errorMessage)
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
#include <utils/ssh/sftpdefs.h>
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -46,9 +48,12 @@ public:
|
||||
|
||||
private slots:
|
||||
void connectToHost();
|
||||
void downloadFile();
|
||||
void handleConnectionError(const QString &errorMessage);
|
||||
void handleSftpOperationFailed(const QString &errorMessage);
|
||||
void handleSftpOperationFinished(Utils::SftpJobId jobId, const QString &error);
|
||||
|
||||
private:
|
||||
Utils::SftpFileSystemModel *m_fsModel;
|
||||
Ui::Window *m_ui;
|
||||
};
|
||||
|
||||
@@ -13,16 +13,13 @@
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Connection Parameters</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
@@ -103,9 +100,63 @@
|
||||
<property name="title">
|
||||
<string>Remote File System</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QTreeView" name="fsView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTreeView" name="fsView"/>
|
||||
<widget class="QPushButton" name="connectButton">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="downloadButton">
|
||||
<property name="text">
|
||||
<string>Download...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Debug output</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="outputTextEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -122,13 +173,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="connectButton">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user