Commit a85cdd59 authored by Gus Grubba's avatar Gus Grubba

Final UI tweaks and fixes.

parent dc2be3bf
...@@ -29,19 +29,28 @@ static const char* kDefaultPx4URL = "http://logs.px4.io/upload"; ...@@ -29,19 +29,28 @@ static const char* kDefaultPx4URL = "http://logs.px4.io/upload";
static const char* kEnableAutoUploadKey = "EnableAutoUploadKey"; static const char* kEnableAutoUploadKey = "EnableAutoUploadKey";
static const char* kEnableAutoStartKey = "EnableAutoStartKey"; static const char* kEnableAutoStartKey = "EnableAutoStartKey";
static const char* kEnableDeletetKey = "EnableDeleteKey"; static const char* kEnableDeletetKey = "EnableDeleteKey";
static const char* kUlogExtension = ".ulg";
static const char* kSidecarExtension = ".uploaded";
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
MavlinkLogFiles::MavlinkLogFiles(MavlinkLogManager* manager, const QString& filePath) MavlinkLogFiles::MavlinkLogFiles(MavlinkLogManager* manager, const QString& filePath, bool newFile)
: _manager(manager) : _manager(manager)
, _size(0) , _size(0)
, _selected(false) , _selected(false)
, _uploading(false) , _uploading(false)
, _progress(0) , _progress(0)
, _writing(false) , _writing(false)
, _uploaded(false)
{ {
QFileInfo fi(filePath); QFileInfo fi(filePath);
_name = fi.baseName(); _name = fi.baseName();
if(!newFile) {
_size = (quint32)fi.size(); _size = (quint32)fi.size();
QString sideCar = filePath;
sideCar.replace(kUlogExtension, kSidecarExtension);
QFileInfo sc(sideCar);
_uploaded = sc.exists();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -85,6 +94,14 @@ MavlinkLogFiles::setWriting(bool writing) ...@@ -85,6 +94,14 @@ MavlinkLogFiles::setWriting(bool writing)
emit writingChanged(); emit writingChanged();
} }
//-----------------------------------------------------------------------------
void
MavlinkLogFiles::setUploaded(bool uploaded)
{
_uploaded = uploaded;
emit uploadedChanged();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CurrentRunningLog::close() void CurrentRunningLog::close()
...@@ -122,14 +139,16 @@ MavlinkLogManager::MavlinkLogManager(QGCApplication* app) ...@@ -122,14 +139,16 @@ MavlinkLogManager::MavlinkLogManager(QGCApplication* app)
_logPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); _logPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
_logPath += "/MavlinkLogs"; _logPath += "/MavlinkLogs";
if(!QDir(_logPath).exists()) { if(!QDir(_logPath).exists()) {
if(QDir().mkpath(_logPath)) { if(!QDir().mkpath(_logPath)) {
qCCritical(MavlinkLogManagerLog) << "Could not create Mavlink log download path:" << _logPath; qCCritical(MavlinkLogManagerLog) << "Could not create Mavlink log download path:" << _logPath;
_loggingDisabled = true; _loggingDisabled = true;
} }
} }
if(!_loggingDisabled) { if(!_loggingDisabled) {
//-- Load current list of logs //-- Load current list of logs
QDirIterator it(_logPath, QStringList() << "*.ulg", QDir::Files); QString filter = "*";
filter += kUlogExtension;
QDirIterator it(_logPath, QStringList() << filter, QDir::Files);
while(it.hasNext()) { while(it.hasNext()) {
_insertNewLog(new MavlinkLogFiles(this, it.next())); _insertNewLog(new MavlinkLogFiles(this, it.next()));
} }
...@@ -153,11 +172,6 @@ MavlinkLogManager::setToolbox(QGCToolbox* toolbox) ...@@ -153,11 +172,6 @@ MavlinkLogManager::setToolbox(QGCToolbox* toolbox)
if(!_loggingDisabled) { if(!_loggingDisabled) {
connect(toolbox->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &MavlinkLogManager::_activeVehicleChanged); connect(toolbox->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &MavlinkLogManager::_activeVehicleChanged);
} }
// _uploadURL = "http://192.168.1.21/px4";
// _uploadURL = "http://192.168.1.9:8080";
// _emailAddress = "gus.grubba.com";
// _description = "Test from QGroundControl - Discard";
// _sendLog("/Users/gus/github/work/logs/simulator.ulg");
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -242,17 +256,16 @@ MavlinkLogManager::uploadLog() ...@@ -242,17 +256,16 @@ MavlinkLogManager::uploadLog()
Q_ASSERT(_currentLogfile); Q_ASSERT(_currentLogfile);
if(_currentLogfile->selected()) { if(_currentLogfile->selected()) {
_currentLogfile->setSelected(false); _currentLogfile->setSelected(false);
if(!_currentLogfile->uploaded() && !_emailAddress.isEmpty() && !_uploadURL.isEmpty()) {
_currentLogfile->setUploading(true); _currentLogfile->setUploading(true);
_currentLogfile->setProgress(0.0); _currentLogfile->setProgress(0.0);
QString filePath = _logPath; QString filePath = _makeFilename(_currentLogfile->name());
filePath += "/";
filePath += _currentLogfile->name();
filePath += ".ulg";
_sendLog(filePath); _sendLog(filePath);
emit uploadingChanged(); emit uploadingChanged();
return; return;
} }
} }
}
_currentLogfile = NULL; _currentLogfile = NULL;
emit uploadingChanged(); emit uploadingChanged();
} }
...@@ -309,14 +322,18 @@ MavlinkLogManager::deleteLog() ...@@ -309,14 +322,18 @@ MavlinkLogManager::deleteLog()
void void
MavlinkLogManager::_deleteLog(MavlinkLogFiles* log) MavlinkLogManager::_deleteLog(MavlinkLogFiles* log)
{ {
QString filePath = _logPath; QString filePath = _makeFilename(log->name());
filePath += "/";
filePath += log->name();
filePath += ".ulg";
QFile gone(filePath); QFile gone(filePath);
if(!gone.remove()) { if(!gone.remove()) {
qCWarning(MavlinkLogManagerLog) << "Could not delete Mavlink log file:" << _logPath; qCWarning(MavlinkLogManagerLog) << "Could not delete Mavlink log file:" << _logPath;
} }
//-- Remove sidecar file (if any)
filePath.replace(kUlogExtension, kSidecarExtension);
QFile sgone(filePath);
if(sgone.exists()) {
sgone.remove();
}
//-- Remove file from list and delete record
_logFiles.removeOne(log); _logFiles.removeOne(log);
delete log; delete log;
emit logFilesChanged(); emit logFilesChanged();
...@@ -494,6 +511,17 @@ MavlinkLogManager::_uploadFinished() ...@@ -494,6 +511,17 @@ MavlinkLogManager::_uploadFinished()
_deleteLog(_currentLogfile); _deleteLog(_currentLogfile);
_currentLogfile = NULL; _currentLogfile = NULL;
} }
} else {
if(_currentLogfile) {
_currentLogfile->setUploaded(true);
//-- Write side-car file to flag it as uploaded
QString sideCar = _makeFilename(_currentLogfile->name());
sideCar.replace(kUlogExtension, kSidecarExtension);
FILE* f = fopen(sideCar.toLatin1().data(), "wb");
if(f) {
fclose(f);
}
}
} }
} else { } else {
qCWarning(MavlinkLogManagerLog) << QString("Log Upload Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString()); qCWarning(MavlinkLogManagerLog) << QString("Log Upload Error: %1 status: %2").arg(reply->errorString(), reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString());
...@@ -525,6 +553,7 @@ MavlinkLogManager::_activeVehicleChanged(Vehicle* vehicle) ...@@ -525,6 +553,7 @@ MavlinkLogManager::_activeVehicleChanged(Vehicle* vehicle)
// connects/disconnects. In reality, if QGC is connected to multiple vehicles, // connects/disconnects. In reality, if QGC is connected to multiple vehicles,
// this is called each time the user switches from one vehicle to another. So // this is called each time the user switches from one vehicle to another. So
// far, I'm working on the assumption that multiple vehicles is a rare exception. // far, I'm working on the assumption that multiple vehicles is a rare exception.
// For now, we only handle one log download at a time.
// Disconnect the previous one (if any) // Disconnect the previous one (if any)
if(_vehicle) { if(_vehicle) {
disconnect(_vehicle, &Vehicle::armedChanged, this, &MavlinkLogManager::_armedChanged); disconnect(_vehicle, &Vehicle::armedChanged, this, &MavlinkLogManager::_armedChanged);
...@@ -586,13 +615,14 @@ MavlinkLogManager::_createNewLog() ...@@ -586,13 +615,14 @@ MavlinkLogManager::_createNewLog()
_currentSavingFile = NULL; _currentSavingFile = NULL;
} }
_currentSavingFile = new CurrentRunningLog; _currentSavingFile = new CurrentRunningLog;
_currentSavingFile->fileName.sprintf("%s/%03d-%s.ulg", _currentSavingFile->fileName.sprintf("%s/%03d-%s%s",
_logPath.toLatin1().data(), _logPath.toLatin1().data(),
_vehicle->id(), _vehicle->id(),
QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz").toLatin1().data()); QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz").toLatin1().data(),
kUlogExtension);
_currentSavingFile->fd = fopen(_currentSavingFile->fileName.toLatin1().data(), "wb"); _currentSavingFile->fd = fopen(_currentSavingFile->fileName.toLatin1().data(), "wb");
if(_currentSavingFile->fd) { if(_currentSavingFile->fd) {
MavlinkLogFiles* newLog = new MavlinkLogFiles(this, _currentSavingFile->fileName); MavlinkLogFiles* newLog = new MavlinkLogFiles(this, _currentSavingFile->fileName, true);
newLog->setWriting(true); newLog->setWriting(true);
_insertNewLog(newLog); _insertNewLog(newLog);
_currentSavingFile->record = newLog; _currentSavingFile->record = newLog;
...@@ -622,3 +652,14 @@ MavlinkLogManager::_armedChanged(bool armed) ...@@ -622,3 +652,14 @@ MavlinkLogManager::_armedChanged(bool armed)
} }
} }
} }
//-----------------------------------------------------------------------------
QString
MavlinkLogManager::_makeFilename(const QString& baseName)
{
QString filePath = _logPath;
filePath += "/";
filePath += baseName;
filePath += kUlogExtension;
return filePath;
}
...@@ -28,7 +28,7 @@ class MavlinkLogFiles : public QObject ...@@ -28,7 +28,7 @@ class MavlinkLogFiles : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
MavlinkLogFiles (MavlinkLogManager* manager, const QString& filePath); MavlinkLogFiles (MavlinkLogManager* manager, const QString& filePath, bool newFile = false);
Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(quint32 size READ size NOTIFY sizeChanged) Q_PROPERTY(quint32 size READ size NOTIFY sizeChanged)
...@@ -36,6 +36,7 @@ public: ...@@ -36,6 +36,7 @@ public:
Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged) Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool writing READ writing NOTIFY writingChanged) Q_PROPERTY(bool writing READ writing NOTIFY writingChanged)
Q_PROPERTY(bool uploaded READ uploaded NOTIFY uploadedChanged)
QString name () { return _name; } QString name () { return _name; }
quint32 size () { return _size; } quint32 size () { return _size; }
...@@ -43,12 +44,14 @@ public: ...@@ -43,12 +44,14 @@ public:
bool uploading () { return _uploading; } bool uploading () { return _uploading; }
qreal progress () { return _progress; } qreal progress () { return _progress; }
bool writing () { return _writing; } bool writing () { return _writing; }
bool uploaded () { return _uploaded; }
void setSelected (bool selected); void setSelected (bool selected);
void setUploading (bool uploading); void setUploading (bool uploading);
void setProgress (qreal progress); void setProgress (qreal progress);
void setWriting (bool writing); void setWriting (bool writing);
void setSize (quint32 size); void setSize (quint32 size);
void setUploaded (bool uploaded);
signals: signals:
void sizeChanged (); void sizeChanged ();
...@@ -56,6 +59,7 @@ signals: ...@@ -56,6 +59,7 @@ signals:
void uploadingChanged (); void uploadingChanged ();
void progressChanged (); void progressChanged ();
void writingChanged (); void writingChanged ();
void uploadedChanged ();
private: private:
MavlinkLogManager* _manager; MavlinkLogManager* _manager;
...@@ -65,6 +69,7 @@ private: ...@@ -65,6 +69,7 @@ private:
bool _uploading; bool _uploading;
qreal _progress; qreal _progress;
bool _writing; bool _writing;
bool _uploaded;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -168,6 +173,7 @@ private: ...@@ -168,6 +173,7 @@ private:
int _getFirstSelected (); int _getFirstSelected ();
void _insertNewLog (MavlinkLogFiles* newLog); void _insertNewLog (MavlinkLogFiles* newLog);
void _deleteLog (MavlinkLogFiles* log); void _deleteLog (MavlinkLogFiles* log);
QString _makeFilename (const QString& baseName);
private: private:
QString _description; QString _description;
......
...@@ -28,6 +28,8 @@ Rectangle { ...@@ -28,6 +28,8 @@ Rectangle {
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 28 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 28
property real _valueWidth: ScreenTools.defaultFontPixelWidth * 24 property real _valueWidth: ScreenTools.defaultFontPixelWidth * 24
property int _selectedCount: 0 property int _selectedCount: 0
property real _columnSpacing: ScreenTools.defaultFontPixelHeight * 0.25
QGCPalette { id: qgcPal } QGCPalette { id: qgcPal }
...@@ -59,6 +61,7 @@ Rectangle { ...@@ -59,6 +61,7 @@ Rectangle {
anchors.margins: ScreenTools.defaultFontPixelWidth anchors.margins: ScreenTools.defaultFontPixelWidth
contentHeight: settingsColumn.height contentHeight: settingsColumn.height
contentWidth: settingsColumn.width contentWidth: settingsColumn.width
flickableDirection: Flickable.VerticalFlick
Column { Column {
id: settingsColumn id: settingsColumn
...@@ -86,7 +89,7 @@ Rectangle { ...@@ -86,7 +89,7 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Column { Column {
id: gcsColumn id: gcsColumn
spacing: ScreenTools.defaultFontPixelWidth spacing: _columnSpacing
anchors.centerIn: parent anchors.centerIn: parent
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
...@@ -148,31 +151,40 @@ Rectangle { ...@@ -148,31 +151,40 @@ Rectangle {
Column { Column {
id: mavlogColumn id: mavlogColumn
width: gcsColumn.width width: gcsColumn.width
spacing: ScreenTools.defaultFontPixelWidth spacing: _columnSpacing
anchors.centerIn: parent anchors.centerIn: parent
//----------------------------------------------------------------- //-----------------------------------------------------------------
//-- Enable auto log on arming
QGCCheckBox {
text: qsTr("Enable automatic logging start when vehicle is armed")
checked: QGroundControl.mavlinkLogManager.enableAutoStart
onClicked: {
QGroundControl.mavlinkLogManager.enableAutoStart = checked
}
}
//-----------------------------------------------------------------
//-- Manual Start/Stop //-- Manual Start/Stop
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
width: _labelWidth
text: qsTr("Manual Start/Stop:")
anchors.verticalCenter: parent.verticalCenter
}
QGCButton { QGCButton {
text: "Start Logging" text: qsTr("Start Logging")
width: (_valueWidth * 0.5) - (ScreenTools.defaultFontPixelWidth * 0.5)
enabled: !QGroundControl.mavlinkLogManager.logRunning && QGroundControl.mavlinkLogManager.canStartLog enabled: !QGroundControl.mavlinkLogManager.logRunning && QGroundControl.mavlinkLogManager.canStartLog
onClicked: QGroundControl.mavlinkLogManager.startLogging() onClicked: QGroundControl.mavlinkLogManager.startLogging()
anchors.verticalCenter: parent.verticalCenter
} }
QGCButton { QGCButton {
text: "Stop Logging" text: qsTr("Stop Logging")
width: (_valueWidth * 0.5) - (ScreenTools.defaultFontPixelWidth * 0.5)
enabled: QGroundControl.mavlinkLogManager.logRunning enabled: QGroundControl.mavlinkLogManager.logRunning
onClicked: QGroundControl.mavlinkLogManager.stopLogging() onClicked: QGroundControl.mavlinkLogManager.stopLogging()
anchors.verticalCenter: parent.verticalCenter
}
}
//-----------------------------------------------------------------
//-- Enable auto log on arming
QGCCheckBox {
text: qsTr("Enable automatic logging")
checked: QGroundControl.mavlinkLogManager.enableAutoStart
onClicked: {
QGroundControl.mavlinkLogManager.enableAutoStart = checked
} }
} }
} }
...@@ -198,7 +210,7 @@ Rectangle { ...@@ -198,7 +210,7 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Column { Column {
id: logColumn id: logColumn
spacing: ScreenTools.defaultFontPixelWidth spacing: _columnSpacing
anchors.centerIn: parent anchors.centerIn: parent
//----------------------------------------------------------------- //-----------------------------------------------------------------
//-- Email address Field //-- Email address Field
...@@ -303,35 +315,37 @@ Rectangle { ...@@ -303,35 +315,37 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Column { Column {
id: logFilesColumn id: logFilesColumn
spacing: ScreenTools.defaultFontPixelWidth spacing: _columnSpacing * 4
anchors.centerIn: parent anchors.centerIn: parent
width: ScreenTools.defaultFontPixelWidth * 68 width: ScreenTools.defaultFontPixelWidth * 68
Rectangle { Rectangle {
width: ScreenTools.defaultFontPixelWidth * 64 width: ScreenTools.defaultFontPixelWidth * 64
height: ScreenTools.defaultFontPixelHeight * 10 height: ScreenTools.defaultFontPixelHeight * 14
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
color: qgcPal.window color: qgcPal.window
border.color: qgcPal.text border.color: qgcPal.text
border.width: 0.5 border.width: 0.5
ListView { ListView {
width: ScreenTools.defaultFontPixelWidth * 56 width: ScreenTools.defaultFontPixelWidth * 56
height: ScreenTools.defaultFontPixelHeight * 8.75 height: ScreenTools.defaultFontPixelHeight * 12
anchors.centerIn: parent anchors.centerIn: parent
orientation: ListView.Vertical orientation: ListView.Vertical
model: QGroundControl.mavlinkLogManager.logFiles model: QGroundControl.mavlinkLogManager.logFiles
clip: true clip: true
delegate: Rectangle { delegate: Rectangle {
width: ScreenTools.defaultFontPixelWidth * 52 width: ScreenTools.defaultFontPixelWidth * 52
height: ScreenTools.defaultFontPixelHeight * 1.25 height: selectCheck.height
color: qgcPal.window color: qgcPal.window
Row { Row {
width: ScreenTools.defaultFontPixelWidth * 50 width: ScreenTools.defaultFontPixelWidth * 50
anchors.centerIn: parent anchors.centerIn: parent
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
QGCCheckBox { QGCCheckBox {
id: selectCheck
width: ScreenTools.defaultFontPixelWidth * 4 width: ScreenTools.defaultFontPixelWidth * 4
checked: object.selected checked: object.selected
enabled: !object.writing && !object.uploading enabled: !object.writing && !object.uploading
anchors.verticalCenter: parent.verticalCenter
onClicked: { onClicked: {
object.selected = checked object.selected = checked
} }
...@@ -340,16 +354,25 @@ Rectangle { ...@@ -340,16 +354,25 @@ Rectangle {
text: object.name text: object.name
width: ScreenTools.defaultFontPixelWidth * 28 width: ScreenTools.defaultFontPixelWidth * 28
color: object.writing ? qgcPal.warningText : qgcPal.text color: object.writing ? qgcPal.warningText : qgcPal.text
anchors.verticalCenter: parent.verticalCenter
} }
QGCLabel { QGCLabel {
text: Number(object.size).toLocaleString(Qt.locale(), 'f', 0) text: Number(object.size).toLocaleString(Qt.locale(), 'f', 0)
visible: !object.uploading visible: !object.uploading && !object.uploaded
width: ScreenTools.defaultFontPixelWidth * 20; width: ScreenTools.defaultFontPixelWidth * 20;
color: object.writing ? qgcPal.warningText : qgcPal.text color: object.writing ? qgcPal.warningText : qgcPal.text
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
anchors.verticalCenter: parent.verticalCenter
}
QGCLabel {
text: "Uploaded"
visible: object.uploaded
width: ScreenTools.defaultFontPixelWidth * 20;
horizontalAlignment: Text.AlignRight
anchors.verticalCenter: parent.verticalCenter
} }
ProgressBar { ProgressBar {
visible: object.uploading visible: object.uploading && !object.uploaded
width: ScreenTools.defaultFontPixelWidth * 20; width: ScreenTools.defaultFontPixelWidth * 20;
height: ScreenTools.defaultFontPixelHeight height: ScreenTools.defaultFontPixelHeight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
......
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