Newer
Older
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "QGCUASFileView.h"
#include "QGCQFileDialog.h"
QGCUASFileView::QGCUASFileView(QWidget *parent, Vehicle* vehicle)
: QWidget(parent)
, _manager(vehicle->uas()->getFileManager())
, _currentCommand(commandNone)
if (vehicle->px4Firmware()) {
_ui.progressBar->reset();
// Connect UI signals
connect(_ui.listFilesButton, &QPushButton::clicked, this, &QGCUASFileView::_refreshTree);
connect(_ui.downloadButton, &QPushButton::clicked, this, &QGCUASFileView::_downloadFile);
connect(_ui.uploadButton, &QPushButton::clicked, this, &QGCUASFileView::_uploadFile);
connect(_ui.treeWidget, &QTreeWidget::currentItemChanged, this, &QGCUASFileView::_currentItemChanged);
// Connect signals from FileManager
connect(_manager, &FileManager::commandProgress, this, &QGCUASFileView::_commandProgress);
connect(_manager, &FileManager::commandComplete, this, &QGCUASFileView::_commandComplete);
connect(_manager, &FileManager::commandError, this, &QGCUASFileView::_commandError);
connect(_manager, &FileManager::listEntry, this, &QGCUASFileView::_listEntryReceived);
} else {
_setAllButtonsEnabled(false);
_ui.statusText->setText(QStringLiteral("Onboard Files not supported by this Vehicle"));
}
/// @brief Downloads the file currently selected in the tree view
void QGCUASFileView::_downloadFile(void)
if (_currentCommand != commandNone) {
qWarning() << QString("Download attempted while another command was in progress: _currentCommand(%1)").arg(_currentCommand);
return;
}
QString downloadToHere = QGCQFileDialog::getExistingDirectory(this,
QGCQFileDialog::ShowDirsOnly | QGCQFileDialog::DontResolveSymlinks);
QTreeWidgetItem* item = _ui.treeWidget->currentItem();
if (item && item->type() == _typeFile) {
do {
QString name = item->text(0).split("\t")[0]; // Strip off file sizes
// If this is the file name and not a directory keep track of the download file name
if (downloadFilename.isEmpty()) {
downloadFilename = name;
_setAllButtonsEnabled(false);
_currentCommand = commandDownload;
_ui.statusText->setText(tr("Downloading: %1").arg(downloadFilename));
_manager->streamPath(path, QDir(downloadToHere));
/// @brief uploads a file into the currently selected directory the tree view
void QGCUASFileView::_uploadFile(void)
{
if (_currentCommand != commandNone) {
qWarning() << QString("Upload attempted while another command was in progress: _currentCommand(%1)").arg(_currentCommand);
return;
}
_ui.statusText->clear();
// get and check directory from list view
QTreeWidgetItem* item = _ui.treeWidget->currentItem();
if (item && item->type() != _typeDir) {
return;
}
// Find complete path for upload directory
QString path;
do {
QString name = item->text(0).split("\t")[0]; // Strip off file sizes
path.prepend("/" + name);
item = item->parent();
} while (item);
QString uploadFromHere = QGCQFileDialog::getOpenFileName(this, tr("Upload File"), QDir::homePath());
_ui.statusText->setText(tr("Uploading: %1").arg(uploadFromHere));
qDebug() << "Upload: " << uploadFromHere << "to path" << path;
_setAllButtonsEnabled(false);
_currentCommand = commandUpload;
_manager->uploadPath(path, uploadFromHere);
/// @brief Called to update the progress of the download.
/// @param value Progress bar value
void QGCUASFileView::_commandProgress(int value)
}
/// @brief Called when an error occurs during a download.
/// @param msg Error message
_setAllButtonsEnabled(true);
_currentCommand = commandNone;
_ui.statusText->setText(tr("Error: %1").arg(msg));
/// @brief Refreshes the directory list tree.
if (_currentCommand != commandNone) {
qWarning() << QString("List attempted while another command was in progress: _currentCommand(%1)").arg(_currentCommand);
return;
}
_walkIndexStack.clear();
_walkItemStack.clear();
_walkIndexStack.append(0);
_walkItemStack.append(_ui.treeWidget->invisibleRootItem());
_setAllButtonsEnabled(false);
_currentCommand = commandList;
/// @brief Adds the specified directory entry to the tree view.
void QGCUASFileView::_listEntryReceived(const QString& entry)
if (_currentCommand != commandList) {
qWarning() << QString("List entry received while no list command in progress: _currentCommand(%1)").arg(_currentCommand);
return;
}
} else if (entry.startsWith("D")) {
if (entry == "D." || entry == "D..") {
return; // Silence maybe-unitialized on type
item = new QTreeWidgetItem(_walkItemStack.last(), type);
item->setText(0, entry.right(entry.size() - 1));
/// @brief Called when a command completes successfully
void QGCUASFileView::_commandComplete(void)
QString statusText;
if (_currentCommand == commandDownload) {
_currentCommand = commandNone;
_setAllButtonsEnabled(true);
statusText = "Download complete";
} else if (_currentCommand == commandUpload) {
_currentCommand = commandNone;
_setAllButtonsEnabled(true);
statusText = "Upload complete";
} else if (_currentCommand == commandList) {
_listComplete();
_ui.statusText->setText(statusText);
_ui.progressBar->reset();
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
}
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));
}
} 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 {
_setAllButtonsEnabled(true);
_currentCommand = commandNone;
}
}
}
void QGCUASFileView::_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
{
Q_UNUSED(previous);
_ui.downloadButton->setEnabled(current ? (current->type() == _typeFile) : false);
_ui.uploadButton->setEnabled(current ? (current->type() == _typeDir) : false);
void QGCUASFileView::_requestDirectoryList(const QString& dir)
void QGCUASFileView::_setAllButtonsEnabled(bool enabled)
_ui.treeWidget->setEnabled(enabled);
_ui.downloadButton->setEnabled(enabled);
_ui.listFilesButton->setEnabled(enabled);
_ui.uploadButton->setEnabled(enabled);
if (enabled) {
_currentItemChanged(_ui.treeWidget->currentItem(), NULL);
}