20 changed files with 625 additions and 254 deletions
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 1.2 |
||||
|
||||
import QGroundControl 1.0 |
||||
import QGroundControl.Palette 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
|
||||
/// Base view control for all Analyze pages |
||||
QGCView { |
||||
id: analyePage |
||||
viewPanel: analyzePanel |
||||
|
||||
property alias pageComponent: pageLoader.sourceComponent |
||||
property alias pageName: pageNameLabel.text |
||||
property alias pageDescription: pageDescriptionLabel.text |
||||
property real availableWidth: width - pageLoader.x |
||||
property real availableHeight: height - pageLoader.y |
||||
|
||||
property real _margins: ScreenTools.defaultFontPixelHeight / 2 |
||||
|
||||
QGCPalette { id: qgcPal; colorGroupEnabled: analyzePanel.enabled } |
||||
|
||||
QGCViewPanel { |
||||
id: analyzePanel |
||||
anchors.fill: parent |
||||
|
||||
QGCFlickable { |
||||
anchors.fill: parent |
||||
contentWidth: pageLoader.x + pageLoader.item.width |
||||
contentHeight: pageLoader.y + pageLoader.item.height |
||||
clip: true |
||||
|
||||
Column { |
||||
id: headingColumn |
||||
width: analyzePanel.width |
||||
spacing: _margins |
||||
|
||||
QGCLabel { |
||||
id: pageNameLabel |
||||
font.pointSize: ScreenTools.largeFontPointSize |
||||
visible: !ScreenTools.isShortScreen |
||||
} |
||||
|
||||
QGCLabel { |
||||
id: pageDescriptionLabel |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
wrapMode: Text.WordWrap |
||||
visible: !ScreenTools.isShortScreen |
||||
} |
||||
} |
||||
|
||||
Loader { |
||||
id: pageLoader |
||||
anchors.topMargin: _margins |
||||
anchors.top: headingColumn.bottom |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
|
||||
/// @file |
||||
/// @brief Setup View |
||||
/// @author Don Gagne <don@thegagnes.com> |
||||
|
||||
import QtQuick 2.3 |
||||
import QtQuick.Controls 1.2 |
||||
|
||||
import QGroundControl 1.0 |
||||
import QGroundControl.Palette 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
|
||||
Rectangle { |
||||
id: setupView |
||||
color: qgcPal.window |
||||
z: QGroundControl.zOrderTopMost |
||||
|
||||
QGCPalette { id: qgcPal; colorGroupEnabled: true } |
||||
|
||||
ExclusiveGroup { id: setupButtonGroup } |
||||
|
||||
readonly property real _defaultTextHeight: ScreenTools.defaultFontPixelHeight |
||||
readonly property real _defaultTextWidth: ScreenTools.defaultFontPixelWidth |
||||
readonly property real _horizontalMargin: _defaultTextWidth / 2 |
||||
readonly property real _verticalMargin: _defaultTextHeight / 2 |
||||
readonly property real _buttonWidth: _defaultTextWidth * 18 |
||||
|
||||
function showGeoTagPanel() { |
||||
panelLoader.source = "GeoTagPage.qml" |
||||
} |
||||
|
||||
Component.onCompleted: showGeoTagPanel() |
||||
|
||||
QGCFlickable { |
||||
id: buttonScroll |
||||
width: buttonColumn.width |
||||
anchors.topMargin: _defaultTextHeight / 2 |
||||
anchors.top: parent.top |
||||
anchors.bottom: parent.bottom |
||||
anchors.leftMargin: _horizontalMargin |
||||
anchors.left: parent.left |
||||
contentHeight: buttonColumn.height |
||||
flickableDirection: Flickable.VerticalFlick |
||||
clip: true |
||||
|
||||
Column { |
||||
id: buttonColumn |
||||
width: _maxButtonWidth |
||||
spacing: _defaultTextHeight / 2 |
||||
|
||||
property real _maxButtonWidth: 0 |
||||
|
||||
Component.onCompleted: reflowWidths() |
||||
|
||||
// I don't know why this does not work |
||||
Connections { |
||||
target: QGroundControl |
||||
onBaseFontPointSizeChanged: buttonColumn.reflowWidths() |
||||
} |
||||
|
||||
function reflowWidths() { |
||||
buttonColumn._maxButtonWidth = 0 |
||||
for (var i = 0; i < children.length; i++) { |
||||
buttonColumn._maxButtonWidth = Math.max(buttonColumn._maxButtonWidth, children[i].width) |
||||
} |
||||
for (var j = 0; j < children.length; j++) { |
||||
children[j].width = buttonColumn._maxButtonWidth |
||||
} |
||||
} |
||||
|
||||
QGCLabel { |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
text: qsTr("Analyze") |
||||
wrapMode: Text.WordWrap |
||||
horizontalAlignment: Text.AlignHCenter |
||||
visible: !ScreenTools.isShortScreen |
||||
} |
||||
|
||||
SubMenuButton { |
||||
id: summaryButton |
||||
imageResource: "/qmlimages/GeoTagIcon.png" |
||||
setupIndicator: false |
||||
checked: true |
||||
exclusiveGroup: setupButtonGroup |
||||
text: "GeoTag Images" |
||||
|
||||
onClicked: showGeoTagPanel() |
||||
} |
||||
} |
||||
} |
||||
|
||||
Rectangle { |
||||
id: divider |
||||
anchors.topMargin: _verticalMargin |
||||
anchors.bottomMargin: _verticalMargin |
||||
anchors.leftMargin: _horizontalMargin |
||||
anchors.left: buttonScroll.right |
||||
anchors.top: parent.top |
||||
anchors.bottom: parent.bottom |
||||
width: 1 |
||||
color: qgcPal.windowShade |
||||
} |
||||
|
||||
Loader { |
||||
id: panelLoader |
||||
anchors.topMargin: _verticalMargin |
||||
anchors.bottomMargin: _verticalMargin |
||||
anchors.leftMargin: _horizontalMargin |
||||
anchors.rightMargin: _horizontalMargin |
||||
anchors.left: divider.right |
||||
anchors.right: parent.right |
||||
anchors.top: parent.top |
||||
anchors.bottom: parent.bottom |
||||
} |
||||
} |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (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 "GeoTagController.h" |
||||
#include "QGCFileDialog.h" |
||||
|
||||
GeoTagController::GeoTagController(void) |
||||
: _progress(0) |
||||
, _inProgress(false) |
||||
{ |
||||
connect(&_worker, &GeoTagWorker::progressChanged, this, &GeoTagController::_workerProgressChanged); |
||||
connect(&_worker, &GeoTagWorker::error, this, &GeoTagController::_workerError); |
||||
connect(&_worker, &GeoTagWorker::started, this, &GeoTagController::inProgressChanged); |
||||
connect(&_worker, &GeoTagWorker::finished, this, &GeoTagController::inProgressChanged); |
||||
} |
||||
|
||||
GeoTagController::~GeoTagController() |
||||
{ |
||||
|
||||
} |
||||
|
||||
void GeoTagController::pickLogFile(void) |
||||
{ |
||||
QString filename = QGCFileDialog::getOpenFileName(NULL, "Select log file load", QString(), "PX4 log file (*.px4log);;All Files (*.*)"); |
||||
if (!filename.isEmpty()) { |
||||
_worker.setLogFile(filename); |
||||
emit logFileChanged(filename); |
||||
} |
||||
} |
||||
|
||||
void GeoTagController::pickImageDirectory(void) |
||||
{ |
||||
QString dir = QGCFileDialog::getExistingDirectory(NULL, "Select image directory"); |
||||
if (!dir.isEmpty()) { |
||||
_worker.setImageDirectory(dir); |
||||
emit imageDirectoryChanged(dir); |
||||
} |
||||
} |
||||
|
||||
void GeoTagController::startTagging(void) |
||||
{ |
||||
_errorMessage.clear(); |
||||
emit errorMessageChanged(_errorMessage); |
||||
_worker.start(); |
||||
} |
||||
|
||||
void GeoTagController::_workerProgressChanged(double progress) |
||||
{ |
||||
_progress = progress; |
||||
emit progressChanged(progress); |
||||
} |
||||
|
||||
void GeoTagController::_workerError(QString errorMessage) |
||||
{ |
||||
_errorMessage = errorMessage; |
||||
emit errorMessageChanged(errorMessage); |
||||
} |
||||
|
||||
GeoTagWorker::GeoTagWorker(void) |
||||
: _cancel(false) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void GeoTagWorker::run(void) |
||||
{ |
||||
_cancel = false; |
||||
emit progressChanged(0); |
||||
|
||||
for (int i=0; i<10;i++) { |
||||
if (_cancel) { |
||||
emit error(tr("Tagging cancelled")); |
||||
return; |
||||
} |
||||
emit progressChanged(i*10); |
||||
sleep(1); |
||||
} |
||||
|
||||
emit progressChanged(100); |
||||
emit taggingComplete(); |
||||
} |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#ifndef GeoTagController_H |
||||
#define GeoTagController_H |
||||
|
||||
#include <QObject> |
||||
#include <QString> |
||||
#include <QThread> |
||||
|
||||
class GeoTagWorker : public QThread |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
GeoTagWorker(void); |
||||
|
||||
QString logFile(void) const { return _logFile; } |
||||
QString imageDirectory(void) const { return _imageDirectory; } |
||||
|
||||
void setLogFile(const QString& logFile) { _logFile = logFile; } |
||||
void setImageDirectory(const QString& imageDirectory) { _imageDirectory = imageDirectory; } |
||||
|
||||
void cancellTagging(void) { _cancel = true; } |
||||
|
||||
protected: |
||||
void run(void) final; |
||||
|
||||
signals: |
||||
void error(QString errorMsg); |
||||
void taggingComplete(void); |
||||
void progressChanged(double progress); |
||||
|
||||
private: |
||||
bool _cancel; |
||||
QString _logFile; |
||||
QString _imageDirectory; |
||||
}; |
||||
|
||||
/// Controller for GeoTagPage.qml. Supports geotagging images based on logfile camera tags.
|
||||
class GeoTagController : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
GeoTagController(void); |
||||
~GeoTagController(); |
||||
|
||||
Q_PROPERTY(QString logFile READ logFile NOTIFY logFileChanged) |
||||
Q_PROPERTY(QString imageDirectory READ imageDirectory NOTIFY imageDirectoryChanged) |
||||
|
||||
/// Set to an error message is geotagging fails
|
||||
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) |
||||
|
||||
/// Progress indicator: 0-100
|
||||
Q_PROPERTY(double progress READ progress NOTIFY progressChanged) |
||||
|
||||
/// true: Currently in the process of tagging
|
||||
Q_PROPERTY(bool inProgress READ inProgress NOTIFY inProgressChanged) |
||||
|
||||
Q_INVOKABLE void pickLogFile(void); |
||||
Q_INVOKABLE void pickImageDirectory(void); |
||||
Q_INVOKABLE void startTagging(void); |
||||
Q_INVOKABLE void cancelTagging(void) { _worker.cancellTagging(); } |
||||
|
||||
QString logFile (void) const { return _worker.logFile(); } |
||||
QString imageDirectory (void) const { return _worker.imageDirectory(); } |
||||
double progress (void) const { return _progress; } |
||||
bool inProgress (void) const { return _worker.isRunning(); } |
||||
QString errorMessage (void) const { return _errorMessage; } |
||||
|
||||
signals: |
||||
void logFileChanged(QString logFile); |
||||
void imageDirectoryChanged(QString imageDirectory); |
||||
void progressChanged(double progress); |
||||
void inProgressChanged(void); |
||||
void errorMessageChanged(QString errorMessage); |
||||
|
||||
private slots: |
||||
void _workerProgressChanged(double progress); |
||||
void _workerError(QString errorMsg); |
||||
|
||||
private: |
||||
QString _errorMessage; |
||||
double _progress; |
||||
bool _inProgress; |
||||
|
||||
GeoTagWorker _worker; |
||||
}; |
||||
|
||||
#endif |
After Width: | Height: | Size: 502 B |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
/**************************************************************************** |
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 1.4 |
||||
import QtQuick.Dialogs 1.2 |
||||
|
||||
import QGroundControl.Palette 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
import QGroundControl.Controllers 1.0 |
||||
|
||||
AnalyzePage { |
||||
id: geoTagPage |
||||
pageComponent: pageComponent |
||||
pageName: qsTr("GeoTag Images (WIP)") |
||||
pageDescription: qsTr("GetTag Images is used to tag a set of images from a survey mission with gps coordinates. You must provide the binary log from the flight as well as the directory which contains the images to tag.") |
||||
|
||||
property real _margin: ScreenTools.defaultFontPixelWidth |
||||
|
||||
GeoTagController { |
||||
id: controller |
||||
} |
||||
|
||||
Component { |
||||
id: pageComponent |
||||
|
||||
Column { |
||||
id: mainColumn |
||||
width: availableWidth |
||||
spacing: _margin |
||||
|
||||
Row { |
||||
spacing: _margin |
||||
|
||||
QGCLabel { |
||||
text: "Log file:" |
||||
} |
||||
|
||||
QGCLabel { |
||||
text: controller.logFile |
||||
} |
||||
|
||||
QGCButton { |
||||
text: qsTr("Select log file") |
||||
onClicked: controller.pickLogFile() |
||||
} |
||||
} |
||||
|
||||
Row { |
||||
spacing: _margin |
||||
|
||||
QGCLabel { |
||||
text: "Image directory:" |
||||
} |
||||
|
||||
QGCLabel { |
||||
text: controller.imageDirectory |
||||
} |
||||
|
||||
QGCButton { |
||||
text: qsTr("Select image directory") |
||||
onClicked: controller.pickImageDirectory() |
||||
} |
||||
} |
||||
|
||||
QGCLabel { text: "NYI - Simulated only" } |
||||
|
||||
QGCButton { |
||||
text: controller.inProgress ? qsTr("Cancel Tagging") : qsTr("Start Tagging") |
||||
|
||||
onClicked: { |
||||
if (controller.inProgress) { |
||||
controller.cancelTagging() |
||||
} else { |
||||
if (controller.logFile == "" || controller.imageDirectory == "") { |
||||
geoTagPage.showMessage(qsTr("Error"), qsTr("You must select a log file and image directory before you can start tagging."), StandardButton.Ok) |
||||
return |
||||
} |
||||
controller.startTagging() |
||||
} |
||||
} |
||||
} |
||||
|
||||
QGCLabel { |
||||
text: controller.errorMessage |
||||
} |
||||
|
||||
ProgressBar { |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
maximumValue: 100 |
||||
value: controller.progress |
||||
} |
||||
} // Column |
||||
} // Component |
||||
} // AnalyzePage |
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
|
||||
/// @file
|
||||
/// @author Don Gagne <don@thegagnes.com>
|
||||
|
||||
#include "SetupViewTest.h" |
||||
#include "MockLink.h" |
||||
#include "MultiVehicleManager.h" |
||||
#include "QGCApplication.h" |
||||
|
||||
void SetupViewTest::_clickThrough_test(void) |
||||
{
|
||||
_createMainWindow(); |
||||
_connectMockLink(); |
||||
|
||||
AutoPilotPlugin* autopilot = qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->autopilotPlugin(); |
||||
Q_ASSERT(autopilot); |
||||
|
||||
// Switch to the Setup view
|
||||
qgcApp()->showSetupView(); |
||||
QTest::qWait(1000); |
||||
|
||||
// Click through fixed buttons
|
||||
qDebug() << "Showing firmware"; |
||||
qgcApp()->_showSetupFirmware(); |
||||
QTest::qWait(1000); |
||||
qDebug() << "Showing parameters"; |
||||
qgcApp()->_showSetupParameters(); |
||||
QTest::qWait(1000); |
||||
qDebug() << "Showing summary"; |
||||
qgcApp()->_showSetupSummary(); |
||||
QTest::qWait(1000); |
||||
|
||||
const QVariantList& components = autopilot->vehicleComponents(); |
||||
foreach(QVariant varComponent, components) { |
||||
VehicleComponent* component = qobject_cast<VehicleComponent*>(qvariant_cast<QObject *>(varComponent)); |
||||
qDebug() << "Showing" << component->name(); |
||||
qgcApp()->_showSetupVehicleComponent(component); |
||||
QTest::qWait(1000); |
||||
} |
||||
|
||||
_disconnectMockLink(); |
||||
_closeMainWindow(); |
||||
} |
@ -1,29 +0,0 @@
@@ -1,29 +0,0 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (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. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
|
||||
/// @file
|
||||
/// @author Don Gagne <don@thegagnes.com>
|
||||
|
||||
#ifndef SetupViewTest_H |
||||
#define SetupViewTest_H |
||||
|
||||
#include "UnitTest.h" |
||||
#include "MainWindow.h" |
||||
|
||||
/// Click through test for Setup View buttons
|
||||
class SetupViewTest : public UnitTest |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void _clickThrough_test(void); |
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue