Commit 3deecfe1 authored by Lorenz Meier's avatar Lorenz Meier

Merge pull request #741 from DonLakeFlyer/MoreFTP

Changed FTP to tree view
parents 2b88c6e9 84cd97ca
......@@ -99,11 +99,6 @@ quint32 QGCUASFileManager::crc32(Request* request, unsigned state)
return state;
}
void QGCUASFileManager::nothingMessage()
{
// FIXME: Connect ui correctly
}
/// @brief Respond to the Ack associated with the Open command with the next Read command.
void QGCUASFileManager::_openAckResponse(Request* openAck)
{
......@@ -220,17 +215,11 @@ void QGCUASFileManager::_listAckResponse(Request* listAck)
_emitErrorMessage(tr("Missing NULL termination in list entry"));
return;
}
// Returned names are prepended with D for directory, F for file, U for unknown
QString s(ptr + 1);
if (*ptr == 'D') {
s.append('/');
}
// Returned names are prepended with D for directory, F for file, U for unknown
if (*ptr == 'F' || *ptr == 'D') {
// put it in the view
_emitStatusMessage(s);
_emitStatusMessage(ptr);
}
// account for the name + NUL
......@@ -243,6 +232,7 @@ void QGCUASFileManager::_listAckResponse(Request* listAck)
// Directory is empty, we're done
Q_ASSERT(listAck->hdr.opcode == kRspAck);
_currentOperation = kCOIdle;
emit listComplete();
} else {
// Possibly more entries to come, need to keep trying till we get EOF
_currentOperation = kCOList;
......@@ -307,6 +297,7 @@ void QGCUASFileManager::receiveMessage(LinkInterface* link, mavlink_message_t me
if (previousOperation == kCOList && errorCode == kErrEOF) {
// This is not an error, just the end of the read loop
emit listComplete();
return;
} else if (previousOperation == kCORead && errorCode == kErrEOF) {
// This is not an error, just the end of the read loop
......
......@@ -43,11 +43,11 @@ public:
signals:
void statusMessage(const QString& msg);
void resetStatusMessages();
void errorMessage(const QString& ms);
void errorMessage(const QString& msg);
void listComplete(void);
public slots:
void receiveMessage(LinkInterface* link, mavlink_message_t message);
void nothingMessage();
void listDirectory(const QString& dirPath);
void downloadPath(const QString& from, const QDir& downloadDir);
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "QGCUASFileView.h"
#include "uas/QGCUASFileManager.h"
#include "ui_QGCUASFileView.h"
#include <QFileDialog>
#include <QDir>
#include <QMessageBox>
QGCUASFileView::QGCUASFileView(QWidget *parent, QGCUASFileManager *manager) :
QWidget(parent),
_manager(manager),
ui(new Ui::QGCUASFileView)
_manager(manager)
{
ui->setupUi(this);
_ui.setupUi(this);
connect(ui->testButton, SIGNAL(clicked()), _manager, SLOT(nothingMessage()));
connect(ui->listFilesButton, SIGNAL(clicked()), this, SLOT(listFiles()));
connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(downloadFiles()));
bool success = connect(_ui.listFilesButton, SIGNAL(clicked()), this, SLOT(_refreshTree()));
Q_ASSERT(success);
success = connect(_ui.downloadButton, SIGNAL(clicked()), this, SLOT(_downloadFiles()));
Q_ASSERT(success);
success = connect(_ui.treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(_currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
Q_ASSERT(success);
Q_UNUSED(success);
}
connect(_manager, SIGNAL(statusMessage(QString)), ui->messageArea, SLOT(appendPlainText(QString)));
connect(_manager, SIGNAL(errorMessage(QString)), ui->messageArea, SLOT(appendPlainText(QString)));
connect(_manager, SIGNAL(resetStatusMessages()), ui->messageArea, SLOT(clear()));
void QGCUASFileView::_downloadFiles(void)
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Download Directory"),
QDir::homePath(),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
// And now download to this location
QString path;
QTreeWidgetItem* item = _ui.treeWidget->currentItem();
if (item && item->type() == _typeFile) {
do {
path.prepend("/" + item->text(0));
item = item->parent();
} while (item);
qDebug() << "Download: " << path;
bool success = connect(_manager, SIGNAL(statusMessage(QString)), this, SLOT(_downloadStatusMessage(QString)));
Q_ASSERT(success);
success = connect(_manager, SIGNAL(errorMessage(QString)), this, SLOT(_downloadStatusMessage(QString)));
Q_ASSERT(success);
Q_UNUSED(success);
_manager->downloadPath(path, QDir(dir));
}
}
QGCUASFileView::~QGCUASFileView()
void QGCUASFileView::_refreshTree(void)
{
delete ui;
QTreeWidgetItem* item;
for (int i=_ui.treeWidget->invisibleRootItem()->childCount(); i>=0; i--) {
item = _ui.treeWidget->takeTopLevelItem(i);
delete item;
}
_walkIndexStack.clear();
_walkItemStack.clear();
_walkIndexStack.append(0);
_walkItemStack.append(_ui.treeWidget->invisibleRootItem());
bool success = connect(_manager, SIGNAL(statusMessage(QString)), this, SLOT(_treeStatusMessage(QString)));
Q_ASSERT(success);
success = connect(_manager, SIGNAL(errorMessage(QString)), this, SLOT(_treeErrorMessage(QString)));
Q_ASSERT(success);
success = connect(_manager, SIGNAL(listComplete(void)), this, SLOT(_listComplete(void)));
Q_ASSERT(success);
Q_UNUSED(success);
qDebug() << "List: /";
_manager->listDirectory("/");
}
void QGCUASFileView::listFiles()
void QGCUASFileView::_treeStatusMessage(const QString& msg)
{
_manager->listDirectory(ui->pathLineEdit->text());
int type;
if (msg.startsWith("F")) {
type = _typeFile;
} else if (msg.startsWith("D")) {
type = _typeDir;
if (msg == "D." || msg == "D..") {
return;
}
} else {
Q_ASSERT(false);
}
QTreeWidgetItem* item;
if (_walkItemStack.count() == 0) {
item = new QTreeWidgetItem(_ui.treeWidget, type);
} else {
item = new QTreeWidgetItem(_walkItemStack.last(), type);
}
Q_CHECK_PTR(item);
item->setText(0, msg.right(msg.size() - 1));
}
void QGCUASFileView::downloadFiles()
void QGCUASFileView::_treeErrorMessage(const QString& msg)
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Download Directory"),
QDir::homePath(),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
// And now download to this location
_manager->downloadPath(ui->pathLineEdit->text(), QDir(dir));
QTreeWidgetItem* item;
if (_walkItemStack.count() == 0) {
item = new QTreeWidgetItem(_ui.treeWidget, _typeError);
} else {
item = new QTreeWidgetItem(_walkItemStack.last(), _typeError);
}
Q_CHECK_PTR(item);
item->setText(0, tr("Error: ") + msg);
}
void QGCUASFileView::_listComplete(void)
{
// Walk the current items, traversing down into directories
Again:
int walkIndex = _walkIndexStack.last();
QTreeWidgetItem* parentItem = _walkItemStack.last();
QTreeWidgetItem* childItem = parentItem->child(walkIndex);
// Loop until we hit a directory
while (childItem && childItem->type() != _typeDir) {
// Move to next index at current level
_walkIndexStack.last() = ++walkIndex;
childItem = parentItem->child(walkIndex);
}
if (childItem) {
// Process this item
QString text = childItem->text(0);
// Move to the next item for processing at this level
_walkIndexStack.last() = ++walkIndex;
// Push this new directory on the stack
_walkItemStack.append(childItem);
_walkIndexStack.append(0);
// Ask for the directory list
QString dir;
for (int i=1; i<_walkItemStack.count(); i++) {
QTreeWidgetItem* item = _walkItemStack[i];
dir.append("/" + item->text(0));
}
qDebug() << "List:" << dir;
_manager->listDirectory(dir);
} else {
// We have run out of items at the this level, pop the stack and keep going at that level
_walkIndexStack.removeLast();
_walkItemStack.removeLast();
if (_walkIndexStack.count() != 0) {
goto Again;
} else {
disconnect(_manager, SIGNAL(statusMessage(QString)), this, SLOT(_treeStatusMessage(QString)));
disconnect(_manager, SIGNAL(errorMessage(QString)), this, SLOT(_treeErrorMessage(QString)));
disconnect(_manager, SIGNAL(listComplete(void)), this, SLOT(_listComplete(void)));
}
}
}
void QGCUASFileView::_downloadStatusMessage(const QString& msg)
{
disconnect(_manager, SIGNAL(statusMessage(QString)), this, SLOT(_downloadStatusMessage(QString)));
disconnect(_manager, SIGNAL(errorMessage(QString)), this, SLOT(_downloadStatusMessage(QString)));
QMessageBox msgBox;
msgBox.setWindowModality(Qt::ApplicationModal);
msgBox.setText(msg);
msgBox.exec();
}
void QGCUASFileView::_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
{
Q_UNUSED(previous);
_ui.downloadButton->setEnabled(current->type() == _typeFile);
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCUASFILEVIEW_H
#define QGCUASFILEVIEW_H
#include <QWidget>
#include "uas/QGCUASFileManager.h"
#include <QTreeWidgetItem>
namespace Ui {
class QGCUASFileView;
}
#include "uas/QGCUASFileManager.h"
#include "ui_QGCUASFileView.h"
class QGCUASFileView : public QWidget
{
......@@ -14,17 +36,27 @@ class QGCUASFileView : public QWidget
public:
explicit QGCUASFileView(QWidget *parent, QGCUASFileManager *manager);
~QGCUASFileView();
public slots:
void listFiles();
void downloadFiles();
protected:
QGCUASFileManager* _manager;
private slots:
void _refreshTree(void);
void _downloadFiles(void);
void _treeStatusMessage(const QString& msg);
void _treeErrorMessage(const QString& msg);
void _listComplete(void);
void _downloadStatusMessage(const QString& msg);
void _currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
private:
Ui::QGCUASFileView *ui;
static const int _typeFile = QTreeWidgetItem::UserType + 1;
static const int _typeDir = QTreeWidgetItem::UserType + 2;
static const int _typeError = QTreeWidgetItem::UserType + 3;
QList<int> _walkIndexStack;
QList<QTreeWidgetItem*> _walkItemStack;
Ui::QGCUASFileView _ui;
};
#endif // QGCUASFILEVIEW_H
......@@ -14,7 +14,7 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<item row="1" column="1">
<widget class="QPushButton" name="listFilesButton">
<property name="text">
<string>List Files</string>
......@@ -22,10 +22,10 @@
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QPlainTextEdit" name="messageArea"/>
</item>
<item row="1" column="0" colspan="3">
<widget class="QTreeWidget" name="treeWidget">
<property name="headerHidden">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
......@@ -33,30 +33,16 @@
</column>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="testButton">
<property name="text">
<string>Null Message</string>
</property>
</widget>
</item>
<item row="3" column="2">
<item row="1" column="2">
<widget class="QPushButton" name="downloadButton">
<property name="text">
<string>Download File</string>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Path:</string>
<string>Download File</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="pathLineEdit"/>
</item>
</layout>
</widget>
<resources/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment