Commit 5116e077 authored by dogmaphobic's avatar dogmaphobic

Merge remote-tracking branch 'Mavlink/master' into orbitOnGuidedBar

* Mavlink/master:
  Parameter search is now typedown style
  Prevent multiple clicks on dialog buttons
  Deploy OpenSSL lib
  Fix trailing slash
  Switch to exact conversion constants
  Copy files in right place
  Add missing headers
  Hack out dynamic font sizing
  Use new polygon drawing tool
  FlightMap supports generic polygon drawing tool
parents b7e6281a d937bd2b
...@@ -63,7 +63,8 @@ WindowsBuild { ...@@ -63,7 +63,8 @@ WindowsBuild {
ReleaseBuild: DLL_QT_DEBUGCHAR = "" ReleaseBuild: DLL_QT_DEBUGCHAR = ""
COPY_FILE_LIST = \ COPY_FILE_LIST = \
$$BASEDIR\\libs\\lib\\sdl\\win32\\SDL.dll \ $$BASEDIR\\libs\\lib\\sdl\\win32\\SDL.dll \
$$BASEDIR\\libs\\thirdParty\\libxbee\\lib\\libxbee.dll $$BASEDIR\\libs\\thirdParty\\libxbee\\lib\\libxbee.dll \
$$BASEDIR\\deploy\\libeay32.dll
for(COPY_FILE, COPY_FILE_LIST) { for(COPY_FILE, COPY_FILE_LIST) {
QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$COPY_FILE\" \"$$DESTDIR_WIN\" QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$COPY_FILE\" \"$$DESTDIR_WIN\"
......
...@@ -17,10 +17,22 @@ ...@@ -17,10 +17,22 @@
#include "QGroundControlQmlGlobal.h" #include "QGroundControlQmlGlobal.h"
#include <QDebug> #include <QDebug>
#include <QtMath>
#include <limits> #include <limits>
#include <cmath> #include <cmath>
// Conversion Constants
// Time
const qreal FactMetaData::UnitConsts_s::secondsPerHour = 3600.0;
// Velocity
const qreal FactMetaData::UnitConsts_s::knotsToKPH = 1.852; // exact, hence weird base for knotsToMetersPerSecond
// Length
const qreal FactMetaData::UnitConsts_s::milesToMeters = 1609.344;
const qreal FactMetaData::UnitConsts_s::feetToMeters = 0.3048;
// Built in translations for all Facts // Built in translations for all Facts
const FactMetaData::BuiltInTranslation_s FactMetaData::_rgBuiltInTranslations[] = { const FactMetaData::BuiltInTranslation_s FactMetaData::_rgBuiltInTranslations[] = {
{ "centi-degrees", "deg", FactMetaData::_centiDegreesToDegrees, FactMetaData::_degreesToCentiDegrees }, { "centi-degrees", "deg", FactMetaData::_centiDegreesToDegrees, FactMetaData::_degreesToCentiDegrees },
...@@ -379,62 +391,62 @@ void FactMetaData::setBuiltInTranslator(void) ...@@ -379,62 +391,62 @@ void FactMetaData::setBuiltInTranslator(void)
QVariant FactMetaData::_degreesToRadians(const QVariant& degrees) QVariant FactMetaData::_degreesToRadians(const QVariant& degrees)
{ {
return QVariant(degrees.toDouble() * (M_PI / 180.0)); return QVariant(qDegreesToRadians(degrees.toDouble()));
} }
QVariant FactMetaData::_radiansToDegrees(const QVariant& radians) QVariant FactMetaData::_radiansToDegrees(const QVariant& radians)
{ {
return QVariant(radians.toDouble() * (180 / M_PI)); return QVariant(qRadiansToDegrees(radians.toDouble()));
} }
QVariant FactMetaData::_centiDegreesToDegrees(const QVariant& centiDegrees) QVariant FactMetaData::_centiDegreesToDegrees(const QVariant& centiDegrees)
{ {
return QVariant(centiDegrees.toFloat() / 100.0f); return QVariant(centiDegrees.toReal() / 100.0);
} }
QVariant FactMetaData::_degreesToCentiDegrees(const QVariant& degrees) QVariant FactMetaData::_degreesToCentiDegrees(const QVariant& degrees)
{ {
return QVariant((unsigned int)(degrees.toFloat() * 100.0f)); return QVariant(qRound(degrees.toReal() * 100.0));
} }
QVariant FactMetaData::_metersToFeet(const QVariant& meters) QVariant FactMetaData::_metersToFeet(const QVariant& meters)
{ {
return QVariant(meters.toDouble() * 3.28083989501); return QVariant(meters.toDouble() * 1.0/constants.feetToMeters);
} }
QVariant FactMetaData::_feetToMeters(const QVariant& feet) QVariant FactMetaData::_feetToMeters(const QVariant& feet)
{ {
return QVariant(feet.toDouble() * 0.305); return QVariant(feet.toDouble() * constants.feetToMeters);
} }
QVariant FactMetaData::_metersPerSecondToMilesPerHour(const QVariant& metersPerSecond) QVariant FactMetaData::_metersPerSecondToMilesPerHour(const QVariant& metersPerSecond)
{ {
return QVariant((metersPerSecond.toDouble() * 0.000621371192) * 60.0 * 60.0); return QVariant((metersPerSecond.toDouble() * 1.0/constants.milesToMeters) * constants.secondsPerHour);
} }
QVariant FactMetaData::_milesPerHourToMetersPerSecond(const QVariant& milesPerHour) QVariant FactMetaData::_milesPerHourToMetersPerSecond(const QVariant& milesPerHour)
{ {
return QVariant((milesPerHour.toDouble() * 1609.344) / (60.0 * 60.0)); return QVariant((milesPerHour.toDouble() * constants.milesToMeters) / constants.secondsPerHour);
} }
QVariant FactMetaData::_metersPerSecondToKilometersPerHour(const QVariant& metersPerSecond) QVariant FactMetaData::_metersPerSecondToKilometersPerHour(const QVariant& metersPerSecond)
{ {
return QVariant((metersPerSecond.toDouble() / 1000.0) * 60.0 * 60.0); return QVariant((metersPerSecond.toDouble() / 1000.0) * constants.secondsPerHour);
} }
QVariant FactMetaData::_kilometersPerHourToMetersPerSecond(const QVariant& kilometersPerHour) QVariant FactMetaData::_kilometersPerHourToMetersPerSecond(const QVariant& kilometersPerHour)
{ {
return QVariant((kilometersPerHour.toDouble() * 1000.0) / (60.0 * 60.0)); return QVariant((kilometersPerHour.toDouble() * 1000.0) / constants.secondsPerHour);
} }
QVariant FactMetaData::_metersPerSecondToKnots(const QVariant& metersPerSecond) QVariant FactMetaData::_metersPerSecondToKnots(const QVariant& metersPerSecond)
{ {
return QVariant(metersPerSecond.toDouble() * 1.94384449244); return QVariant(metersPerSecond.toDouble() * constants.secondsPerHour / (1000.0 * constants.knotsToKPH));
} }
QVariant FactMetaData::_knotsToMetersPerSecond(const QVariant& knots) QVariant FactMetaData::_knotsToMetersPerSecond(const QVariant& knots)
{ {
return QVariant(knots.toDouble() * 0.51444444444); return QVariant(knots.toDouble() * (constants.knotsToKPH / (1000.0 * constants.secondsPerHour)));
} }
QVariant FactMetaData::_percentToNorm(const QVariant& percent) QVariant FactMetaData::_percentToNorm(const QVariant& percent)
......
...@@ -188,6 +188,14 @@ private: ...@@ -188,6 +188,14 @@ private:
bool _rebootRequired; bool _rebootRequired;
double _increment; double _increment;
// Exact conversion constants
static const struct UnitConsts_s {
static const qreal secondsPerHour;
static const qreal knotsToKPH;
static const qreal milesToMeters;
static const qreal feetToMeters;
} constants;
struct BuiltInTranslation_s { struct BuiltInTranslation_s {
const char* rawUnits; const char* rawUnits;
const char* cookedUnits; const char* cookedUnits;
...@@ -195,6 +203,7 @@ private: ...@@ -195,6 +203,7 @@ private:
Translator cookedTranslator; Translator cookedTranslator;
}; };
static const BuiltInTranslation_s _rgBuiltInTranslations[]; static const BuiltInTranslation_s _rgBuiltInTranslations[];
static const AppSettingsTranslation_s _rgAppSettingsTranslations[]; static const AppSettingsTranslation_s _rgAppSettingsTranslations[];
......
...@@ -128,4 +128,152 @@ Map { ...@@ -128,4 +128,152 @@ Map {
label: "Q" label: "Q"
} }
} }
//---- Polygon drawing code
//
// Usage:
//
// Connections {
// target: map.polygonDraw
//
// onPolygonStarted: {
// // Polygon creation has started
// }
//
// onPolygonFinished: {
// // Polygon capture complete, coordinates signal variable contains the polygon points
// }
// }
//
// map.polygonDraqw.startPolgyon() - begin capturing a new polygon
// map.polygonDraqw.endPolygon() - end capture (right-click will also end capture)
// Not sure why this is needed, but trying to reference polygonDrawer directly from other code doesn't work
property alias polygonDraw: polygonDrawer
QGCLabel {
id: polygonHelp
anchors.topMargin: parent.height - ScreenTools.availableHeight
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
text: qsTr("Click to add point %1").arg(ScreenTools.isMobile || !polygonDrawer.polygonReady ? "" : qsTr("- Right Click to end polygon"))
visible: polygonDrawer.drawingPolygon
}
MouseArea {
id: polygonDrawer
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
visible: drawingPolygon
z: 1000 // Hack to fix MouseArea layering for now
property alias drawingPolygon: polygonDrawer.hoverEnabled
property bool polygonReady: polygonDrawerPolygon.path.length > 3 ///< true: enough points have been captured to create a closed polygon
/// New polygon capture has started
signal polygonStarted
/// Polygon capture is complete
/// @param coordinates Map coordinates for the polygon points
signal polygonFinished(var coordinates)
/// Begin capturing a new polygon
/// polygonStarted will be signalled
function startPolygon() {
polygonDrawer.drawingPolygon = true
polygonDrawer._clearPolygon()
polygonDrawer.polygonStarted()
}
/// Finish capturing the polygon
/// polygonFinished will be signalled
/// @return true: polygon completed, false: not enough points to complete polygon
function finishPolygon() {
if (!polygonDrawer.polygonReady) {
return false
}
var polygonPath = polygonDrawerPolygon.path
polygonPath.pop() // get rid of drag coordinate
polygonDrawer._clearPolygon()
polygonDrawer.drawingPolygon = false
polygonDrawer.polygonFinished(polygonPath)
return true
}
function _clearPolygon() {
// Simpler methods to clear the path simply don't work due to bugs. This craziness does.
var bogusCoord = _map.toCoordinate(Qt.point(height/2, width/2))
polygonDrawerPolygon.path = [ bogusCoord, bogusCoord ]
polygonDrawerNextPoint.path = [ bogusCoord, bogusCoord ]
polygonDrawerPolygon.path = [ ]
polygonDrawerNextPoint.path = [ ]
}
onClicked: {
if (mouse.button == Qt.LeftButton) {
if (polygonDrawerPolygon.path.length > 2) {
// Make sure the new line doesn't intersect the existing polygon
var lastSegment = polygonDrawerPolygon.path.length - 2
var newLineA = _map.fromCoordinate(polygonDrawerPolygon.path[lastSegment], false /* clipToViewPort */)
var newLineB = _map.fromCoordinate(polygonDrawerPolygon.path[lastSegment+1], false /* clipToViewPort */)
for (var i=0; i<lastSegment; i++) {
var oldLineA = _map.fromCoordinate(polygonDrawerPolygon.path[i], false /* clipToViewPort */)
var oldLineB = _map.fromCoordinate(polygonDrawerPolygon.path[i+1], false /* clipToViewPort */)
if (QGroundControl.linesIntersect(newLineA, newLineB, oldLineA, oldLineB)) {
return;
}
}
}
var clickCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y))
var polygonPath = polygonDrawerPolygon.path
if (polygonPath.length == 0) {
// Add first coordinate
polygonPath.push(clickCoordinate)
} else {
// Update finalized coordinate
polygonPath[polygonDrawerPolygon.path.length - 1] = clickCoordinate
}
// Add next drag coordinate
polygonPath.push(clickCoordinate)
polygonDrawerPolygon.path = polygonPath
} else if (polygonDrawer.polygonReady) {
finishPolygon()
}
}
onPositionChanged: {
if (polygonDrawerPolygon.path.length) {
var dragCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y))
// Update drag line
polygonDrawerNextPoint.path = [ polygonDrawerPolygon.path[polygonDrawerPolygon.path.length - 2], dragCoordinate ]
// Update drag coordinate
var polygonPath = polygonDrawerPolygon.path
polygonPath[polygonDrawerPolygon.path.length - 1] = dragCoordinate
polygonDrawerPolygon.path = polygonPath
}
}
}
MapPolygon {
id: polygonDrawerPolygon
color: "blue"
opacity: 0.5
visible: polygonDrawer.drawingPolygon
}
MapPolyline {
id: polygonDrawerNextPoint
line.color: "green"
line.width: 5
visible: polygonDrawer.drawingPolygon
}
//---- End Polygon Drawing code
} // Map } // Map
...@@ -19,8 +19,7 @@ Rectangle { ...@@ -19,8 +19,7 @@ Rectangle {
//property real availableWidth ///< Width for control //property real availableWidth ///< Width for control
//property var missionItem ///< Mission Item for editor //property var missionItem ///< Mission Item for editor
property bool _addPointsMode: false property real _margin: ScreenTools.defaultFontPixelWidth / 2
property real _margin: ScreenTools.defaultFontPixelWidth / 2
QGCPalette { id: qgcPal; colorGroupEnabled: true } QGCPalette { id: qgcPal; colorGroupEnabled: true }
...@@ -32,16 +31,6 @@ Rectangle { ...@@ -32,16 +31,6 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
spacing: _margin spacing: _margin
Connections {
target: editorMap
onMapClicked: {
if (_addPointsMode) {
missionItem.addPolygonCoordinate(coordinate)
}
}
}
QGCLabel { QGCLabel {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize font.pointSize: ScreenTools.smallFontPointSize
...@@ -109,14 +98,29 @@ Rectangle { ...@@ -109,14 +98,29 @@ Rectangle {
} }
} }
Connections {
target: editorMap.polygonDraw
onPolygonStarted: {
missionItem.clearPolygon()
}
onPolygonFinished: {
for (var i=0; i<coordinates.length; i++) {
missionItem.addPolygonCoordinate(coordinates[i])
}
}
}
QGCButton { QGCButton {
text: _addPointsMode ? qsTr("Finish Polygon") : qsTr("Draw Polygon") text: editorMap.polygonDraw.drawingPolygon ? qsTr("Finish Polygon") : qsTr("Draw Polygon")
enabled: (editorMap.polygonDraw.drawingPolygon && editorMap.polygonDraw.polygonReady) || !editorMap.polygonDraw.drawingPolygon
onClicked: { onClicked: {
if (_addPointsMode) { if (editorMap.polygonDraw.drawingPolygon) {
_addPointsMode = false editorMap.polygonDraw.finishPolygon()
} else { } else {
missionItem.clearPolygon() editorMap.polygonDraw.startPolygon()
_addPointsMode = true
} }
} }
} }
......
...@@ -32,9 +32,8 @@ QGCView { ...@@ -32,9 +32,8 @@ QGCView {
property Fact _editorDialogFact: Fact { } property Fact _editorDialogFact: Fact { }
property int _rowHeight: ScreenTools.defaultFontPixelHeight * 2 property int _rowHeight: ScreenTools.defaultFontPixelHeight * 2
property int _rowWidth: 10 // Dynamic adjusted at runtime property int _rowWidth: 10 // Dynamic adjusted at runtime
property bool _searchFilter: false ///< true: showing results of search property bool _searchFilter: searchText.text != "" ///< true: showing results of search
property var _searchResults ///< List of parameter names from search results property var _searchResults ///< List of parameter names from search results
property string _currentGroup: ""
property bool _showRCToParam: !ScreenTools.isMobile && QGroundControl.multiVehicleManager.activeVehicle.px4Firmware property bool _showRCToParam: !ScreenTools.isMobile && QGroundControl.multiVehicleManager.activeVehicle.px4Firmware
ParameterEditorController { ParameterEditorController {
...@@ -55,34 +54,24 @@ QGCView { ...@@ -55,34 +54,24 @@ QGCView {
id: header id: header
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
height: searchText.height + ScreenTools.defaultFontPixelHeight / 3
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
QGCTextField { QGCLabel {
id: searchText anchors.baseline: clearButton.baseline
text: qsTr("Search:")
} }
QGCButton { QGCTextField {
anchors.top: searchText.top id: searchText
anchors.bottom: searchText.bottom anchors.baseline: clearButton.baseline
text: qsTr("Search") text: controller.searchText
onClicked: { onDisplayTextChanged: controller.searchText = displayText
_searchResults = controller.searchParametersForComponent(-1, searchText.text)
_searchFilter = true
}
} }
QGCButton { QGCButton {
anchors.top: searchText.top id: clearButton
anchors.bottom: searchText.bottom text: qsTr("Clear")
text: qsTr("Clear") onClicked: searchText.text = ""
visible: _searchFilter
onClicked: {
searchText.text = ""
_searchFilter = false
hideDialog()
}
} }
} // Row - Header } // Row - Header
...@@ -132,184 +121,135 @@ QGCView { ...@@ -132,184 +121,135 @@ QGCView {
} }
} }
//--------------------------------------------- /// Group buttons
//-- Contents QGCFlickable {
Loader { id : groupScroll
anchors.left: parent.left width: ScreenTools.defaultFontPixelWidth * 25
anchors.right: parent.right
anchors.top: header.bottom anchors.top: header.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
sourceComponent: _searchFilter ? searchResultsViewComponent: groupedViewComponent clip: true
} pixelAligned: true
} contentHeight: groupedViewComponentColumn.height
contentWidth: groupedViewComponentColumn.width
flickableDirection: Flickable.VerticalFlick
visible: !_searchFilter
//-- Parameter Groups Column {
Component { id: groupedViewComponentColumn
id: groupedViewComponent spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
Row {
spacing: ScreenTools.defaultFontPixelWidth * 0.5 Repeater {
//-- Parameter Groups model: controller.componentIds
QGCFlickable {
id : groupScroll Column {
width: ScreenTools.defaultFontPixelWidth * 25 id: componentColumn
height: parent.height spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
clip: true
pixelAligned: true readonly property int componentId: modelData
contentHeight: groupedViewComponentColumn.height
contentWidth: groupedViewComponentColumn.width QGCLabel {
flickableDirection: Flickable.VerticalFlick text: qsTr("Component #: %1").arg(componentId.toString())
Column { font.family: ScreenTools.demiboldFontFamily
id: groupedViewComponentColumn anchors.horizontalCenter: parent.horizontalCenter
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25) }
Repeater {
model: controller.componentIds ExclusiveGroup { id: groupGroup }
Column {
id: componentColumn Repeater {
readonly property int componentId: parseInt(modelData) model: controller.getGroupsForComponent(componentId)
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
QGCLabel { QGCButton {
text: qsTr("Component #: %1").arg(componentId.toString()) width: ScreenTools.defaultFontPixelWidth * 25
font.family: ScreenTools.demiboldFontFamily text: groupName
anchors.horizontalCenter: parent.horizontalCenter height: _rowHeight
} exclusiveGroup: setupButtonGroup
ExclusiveGroup { id: groupGroup }
Repeater { readonly property string groupName: modelData
model: controller.getGroupsForComponent(componentId)
QGCButton { onClicked: {
width: ScreenTools.defaultFontPixelWidth * 25 checked = true
text: modelData _rowWidth = 10
height: _rowHeight controller.currentComponentId = componentId
exclusiveGroup: setupButtonGroup controller.currentGroup = groupName
onClicked: {
checked = true
// Clear the rows from the component first. This allows us to change the componentId without
// breaking any bindings.
factRowsLoader.parameterNames = [ ]
_rowWidth = 10
factRowsLoader.componentId = componentId
factRowsLoader.parameterNames = controller.getParametersForGroup(componentId, modelData)
_currentGroup = modelData
factScrollView.contentX = 0
factScrollView.contentY = 0
}
} }
} }
} }
} }
} }
} }
Rectangle {
color: __qgcPal.text
width: 1
height: parent.height
opacity: 0.1
}
//-- Parameters
QGCFlickable {
id: factScrollView
width: parent.width - groupScroll.width
height: parent.height
contentHeight: factRowsLoader.height
contentWidth: _rowWidth
boundsBehavior: Flickable.OvershootBounds
pixelAligned: true
clip: true
Loader {
id: factRowsLoader
sourceComponent: factRowsComponent
property int componentId: controller.componentIds[0]
property var parameterNames: controller.getParametersForGroup(componentId, controller.getGroupsForComponent(componentId)[0])
onLoaded: {
_currentGroup = controller.getGroupsForComponent(controller.componentIds[0])[0]
}
}
}
} }
}
//--------------------------------------------- /// Parameter list
// Search result view ListView {
Component { id: editorListView
id: searchResultsViewComponent anchors.leftMargin: ScreenTools.defaultFontPixelWidth
Item { anchors.left: _searchFilter ? parent.left : groupScroll.right
QGCFlickable { anchors.right: parent.right
id: factScrollView anchors.top: header.bottom
width: parent.width anchors.bottom: parent.bottom
height: parent.height orientation: ListView.Vertical
contentHeight: factRowsLoader.height model: controller.parameters
contentWidth: _rowWidth cacheBuffer: height > 0 ? height * 2 : 0
boundsBehavior: Flickable.OvershootBounds clip: true
pixelAligned: true
clip: true delegate: Rectangle {
Loader { height: _rowHeight
id: factRowsLoader width: _rowWidth
sourceComponent: factRowsComponent color: Qt.rgba(0,0,0,0)
property int componentId: -1
property var parameterNames: _searchResults Row {
} id: factRow
} spacing: Math.ceil(ScreenTools.defaultFontPixelWidth * 0.5)
} anchors.verticalCenter: parent.verticalCenter
}
property Fact modelFact: object
QGCLabel {
id: nameLabel
width: ScreenTools.defaultFontPixelWidth * 20
text: factRow.modelFact.name
clip: true
}
//--------------------------------------------- QGCLabel {
// Paremeters view id: valueLabel
Component { width: ScreenTools.defaultFontPixelWidth * 20
id: factRowsComponent color: factRow.modelFact.defaultValueAvailable ? (factRow.modelFact.valueEqualsDefault ? __qgcPal.text : __qgcPal.warningText) : __qgcPal.text
Column { text: factRow.modelFact.enumStrings.length == 0 ? factRow.modelFact.valueString + " " + factRow.modelFact.units : factRow.modelFact.enumStringValue
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25) clip: true
Repeater {
model: parameterNames
Rectangle {
height: _rowHeight
width: _rowWidth
color: Qt.rgba(0,0,0,0)
Row {
id: factRow
property Fact modelFact: controller.getParameterFact(componentId, modelData)
spacing: Math.ceil(ScreenTools.defaultFontPixelWidth * 0.5)
anchors.verticalCenter: parent.verticalCenter
QGCLabel {
id: nameLabel
width: ScreenTools.defaultFontPixelWidth * 20
text: factRow.modelFact.name
clip: true
}
QGCLabel {
id: valueLabel
width: ScreenTools.defaultFontPixelWidth * 20
color: factRow.modelFact.defaultValueAvailable ? (factRow.modelFact.valueEqualsDefault ? __qgcPal.text : __qgcPal.warningText) : __qgcPal.text
text: factRow.modelFact.enumStrings.length == 0 ? factRow.modelFact.valueString + " " + factRow.modelFact.units : factRow.modelFact.enumStringValue
clip: true
}
QGCLabel {
text: factRow.modelFact.shortDescription
}
Component.onCompleted: {
if(_rowWidth < factRow.width + ScreenTools.defaultFontPixelWidth) {
_rowWidth = factRow.width + ScreenTools.defaultFontPixelWidth
}
}
} }
Rectangle {
width: _rowWidth QGCLabel {
height: 1 text: factRow.modelFact.shortDescription
color: __qgcPal.text
opacity: 0.15
anchors.bottom: parent.bottom
anchors.left: parent.left
} }
MouseArea {
anchors.fill: parent Component.onCompleted: {
acceptedButtons: Qt.LeftButton if(_rowWidth < factRow.width + ScreenTools.defaultFontPixelWidth) {
onClicked: { _rowWidth = factRow.width + ScreenTools.defaultFontPixelWidth
_editorDialogFact = factRow.modelFact
showDialog(editorDialogComponent, qsTr("Parameter Editor"), qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Save)
} }
} }
} }
Rectangle {
width: _rowWidth
height: 1
color: __qgcPal.text
opacity: 0.15
anchors.bottom: parent.bottom
anchors.left: parent.left
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onClicked: {
_editorDialogFact = factRow.modelFact
showDialog(editorDialogComponent, qsTr("Parameter Editor"), qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Save)
}
}
} }
} }
} } // QGCViewPanel
Component { Component {
id: editorDialogComponent id: editorDialogComponent
...@@ -320,44 +260,6 @@ QGCView { ...@@ -320,44 +260,6 @@ QGCView {
} }
} }
Component {
id: searchDialogComponent
QGCViewDialog {
function accept() {
_searchResults = controller.searchParametersForComponent(-1, searchFor.text, true /*searchInName.checked*/, true /*searchInDescriptions.checked*/)
_searchFilter = true
hideDialog()
}
function reject() {
_searchFilter = false
hideDialog()
}
QGCLabel {
id: searchForLabel
text: qsTr("Search for:")
}
QGCTextField {
id: searchFor
anchors.topMargin: defaultTextHeight / 3
anchors.top: searchForLabel.bottom
width: ScreenTools.defaultFontPixelWidth * 20
}
QGCLabel {
anchors.topMargin: defaultTextHeight
anchors.top: searchFor.bottom
width: parent.width
wrapMode: Text.WordWrap
text: qsTr("Hint: Leave 'Search For' blank and click Apply to list all parameters sorted by name.")
}
}
}
Component { Component {
id: mobileFilePicker id: mobileFilePicker
......
...@@ -25,14 +25,20 @@ ...@@ -25,14 +25,20 @@
/// @Brief Constructs a new ParameterEditorController Widget. This widget is used within the PX4VehicleConfig set of screens. /// @Brief Constructs a new ParameterEditorController Widget. This widget is used within the PX4VehicleConfig set of screens.
ParameterEditorController::ParameterEditorController(void) ParameterEditorController::ParameterEditorController(void)
: _currentComponentId(_vehicle->defaultComponentId())
, _parameters(new QmlObjectListModel(this))
{ {
if (_autopilot) { const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap(); foreach (int componentId, groupMap.keys()) {
_componentIds += QString("%1").arg(componentId);
foreach (int componentId, groupMap.keys()) {
_componentIds += QString("%1").arg(componentId);
}
} }
_currentGroup = groupMap[_currentComponentId].keys()[0];
_updateParameters();
connect(this, &ParameterEditorController::searchTextChanged, this, &ParameterEditorController::_updateParameters);
connect(this, &ParameterEditorController::currentComponentIdChanged, this, &ParameterEditorController::_updateParameters);
connect(this, &ParameterEditorController::currentGroupChanged, this, &ParameterEditorController::_updateParameters);
} }
ParameterEditorController::~ParameterEditorController() ParameterEditorController::~ParameterEditorController()
...@@ -42,16 +48,16 @@ ParameterEditorController::~ParameterEditorController() ...@@ -42,16 +48,16 @@ ParameterEditorController::~ParameterEditorController()
QStringList ParameterEditorController::getGroupsForComponent(int componentId) QStringList ParameterEditorController::getGroupsForComponent(int componentId)
{ {
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap(); const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
return groupMap[componentId].keys(); return groupMap[componentId].keys();
} }
QStringList ParameterEditorController::getParametersForGroup(int componentId, QString group) QStringList ParameterEditorController::getParametersForGroup(int componentId, QString group)
{ {
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap(); const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
return groupMap[componentId][group]; return groupMap[componentId][group];
} }
QStringList ParameterEditorController::searchParametersForComponent(int componentId, const QString& searchText, bool searchInName, bool searchInDescriptions) QStringList ParameterEditorController::searchParametersForComponent(int componentId, const QString& searchText, bool searchInName, bool searchInDescriptions)
...@@ -78,8 +84,8 @@ QStringList ParameterEditorController::searchParametersForComponent(int componen ...@@ -78,8 +84,8 @@ QStringList ParameterEditorController::searchParametersForComponent(int componen
void ParameterEditorController::clearRCToParam(void) void ParameterEditorController::clearRCToParam(void)
{ {
Q_ASSERT(_uas); Q_ASSERT(_uas);
_uas->unsetRCToParameterMap(); _uas->unsetRCToParameterMap();
} }
void ParameterEditorController::saveToFile(const QString& filename) void ParameterEditorController::saveToFile(const QString& filename)
...@@ -92,15 +98,15 @@ void ParameterEditorController::saveToFile(const QString& filename) ...@@ -92,15 +98,15 @@ void ParameterEditorController::saveToFile(const QString& filename)
if (!filename.isEmpty()) { if (!filename.isEmpty()) {
QFile file(filename); QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qgcApp()->showMessage(QString("Unable to create file: %1").arg(filename)); qgcApp()->showMessage(QString("Unable to create file: %1").arg(filename));
return; return;
} }
QTextStream stream(&file); QTextStream stream(&file);
_autopilot->writeParametersToStream(stream); _autopilot->writeParametersToStream(stream);
file.close(); file.close();
} }
} }
void ParameterEditorController::saveToFilePicker(void) void ParameterEditorController::saveToFilePicker(void)
...@@ -156,7 +162,7 @@ void ParameterEditorController::loadFromFilePicker(void) ...@@ -156,7 +162,7 @@ void ParameterEditorController::loadFromFilePicker(void)
void ParameterEditorController::refresh(void) void ParameterEditorController::refresh(void)
{ {
_autopilot->refreshAllParameters(); _autopilot->refreshAllParameters();
} }
void ParameterEditorController::resetAllToDefaults(void) void ParameterEditorController::resetAllToDefaults(void)
...@@ -170,8 +176,31 @@ void ParameterEditorController::setRCToParam(const QString& paramName) ...@@ -170,8 +176,31 @@ void ParameterEditorController::setRCToParam(const QString& paramName)
#ifdef __mobile__ #ifdef __mobile__
Q_UNUSED(paramName) Q_UNUSED(paramName)
#else #else
Q_ASSERT(_uas); Q_ASSERT(_uas);
QGCMapRCToParamDialog * d = new QGCMapRCToParamDialog(paramName, _uas, qgcApp()->toolbox()->multiVehicleManager(), MainWindow::instance()); QGCMapRCToParamDialog * d = new QGCMapRCToParamDialog(paramName, _uas, qgcApp()->toolbox()->multiVehicleManager(), MainWindow::instance());
d->exec(); d->exec();
#endif #endif
} }
void ParameterEditorController::_updateParameters(void)
{
QObjectList newParameterList;
if (_searchText.isEmpty()) {
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
foreach (const QString& parameter, groupMap[_currentComponentId][_currentGroup]) {
newParameterList.append(_autopilot->getParameterFact(_currentComponentId, parameter));
}
} else {
foreach(const QString &parameter, _autopilot->parameterNames(_vehicle->defaultComponentId())) {
Fact* fact = _autopilot->getParameterFact(_vehicle->defaultComponentId(), parameter);
if (fact->name().contains(_searchText, Qt::CaseInsensitive) ||
fact->shortDescription().contains(_searchText, Qt::CaseInsensitive) ||
fact->longDescription().contains(_searchText, Qt::CaseInsensitive)) {
newParameterList.append(fact);
}
}
}
_parameters->swapObjectList(newParameterList);
}
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "AutoPilotPlugin.h" #include "AutoPilotPlugin.h"
#include "UASInterface.h" #include "UASInterface.h"
#include "FactPanelController.h" #include "FactPanelController.h"
#include "QmlObjectListModel.h"
class ParameterEditorController : public FactPanelController class ParameterEditorController : public FactPanelController
{ {
...@@ -29,7 +30,11 @@ public: ...@@ -29,7 +30,11 @@ public:
ParameterEditorController(void); ParameterEditorController(void);
~ParameterEditorController(); ~ParameterEditorController();
Q_PROPERTY(QStringList componentIds MEMBER _componentIds CONSTANT) Q_PROPERTY(QString searchText MEMBER _searchText NOTIFY searchTextChanged)
Q_PROPERTY(int currentComponentId MEMBER _currentComponentId NOTIFY currentComponentIdChanged)
Q_PROPERTY(QString currentGroup MEMBER _currentGroup NOTIFY currentGroupChanged)
Q_PROPERTY(QmlObjectListModel* parameters MEMBER _parameters CONSTANT)
Q_PROPERTY(QVariantList componentIds MEMBER _componentIds CONSTANT)
Q_INVOKABLE QStringList getGroupsForComponent(int componentId); Q_INVOKABLE QStringList getGroupsForComponent(int componentId);
Q_INVOKABLE QStringList getParametersForGroup(int componentId, QString group); Q_INVOKABLE QStringList getParametersForGroup(int componentId, QString group);
...@@ -47,10 +52,20 @@ public: ...@@ -47,10 +52,20 @@ public:
QList<QObject*> model(void); QList<QObject*> model(void);
signals: signals:
void searchTextChanged(QString searchText);
void currentComponentIdChanged(int componentId);
void currentGroupChanged(QString group);
void showErrorMessage(const QString& errorMsg); void showErrorMessage(const QString& errorMsg);
private slots:
void _updateParameters(void);
private: private:
QStringList _componentIds; QVariantList _componentIds;
QString _searchText;
int _currentComponentId;
QString _currentGroup;
QmlObjectListModel* _parameters;
}; };
#endif #endif
...@@ -123,6 +123,9 @@ FactPanel { ...@@ -123,6 +123,9 @@ FactPanel {
return return
} }
__rejectButton.enabled = true
__acceptButton.enabled = true
__stopAllAnimations() __stopAllAnimations()
__dialogCharWidth = charWidth __dialogCharWidth = charWidth
...@@ -144,6 +147,9 @@ FactPanel { ...@@ -144,6 +147,9 @@ FactPanel {
return return
} }
__rejectButton.enabled = true
__acceptButton.enabled = true
__stopAllAnimations() __stopAllAnimations()
__dialogCharWidth = showDialogDefaultWidth __dialogCharWidth = showDialogDefaultWidth
...@@ -302,7 +308,10 @@ FactPanel { ...@@ -302,7 +308,10 @@ FactPanel {
anchors.right: __acceptButton.visible ? __acceptButton.left : parent.right anchors.right: __acceptButton.visible ? __acceptButton.left : parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
onClicked: __dialogComponentLoader.item.reject() onClicked: {
enabled = false // prevent multiple clicks
__dialogComponentLoader.item.reject()
}
} }
QGCButton { QGCButton {
...@@ -311,6 +320,7 @@ FactPanel { ...@@ -311,6 +320,7 @@ FactPanel {
primary: true primary: true
onClicked: { onClicked: {
enabled = false // prevent multiple clicks
__dialogComponentLoader.item.accept() __dialogComponentLoader.item.accept()
} }
} }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "QGroundControlQmlGlobal.h" #include "QGroundControlQmlGlobal.h"
#include <QSettings> #include <QSettings>
#include <QLineF>
#include <QPointF>
static const char* kQmlGlobalKeyName = "QGCQml"; static const char* kQmlGlobalKeyName = "QGCQml";
...@@ -264,3 +266,11 @@ Fact* QGroundControlQmlGlobal::speedUnits(void) ...@@ -264,3 +266,11 @@ Fact* QGroundControlQmlGlobal::speedUnits(void)
return _speedUnitsFact; return _speedUnitsFact;
} }
bool QGroundControlQmlGlobal::linesIntersect(QPointF line1A, QPointF line1B, QPointF line2A, QPointF line2B)
{
QPointF intersectPoint;
return QLineF(line1A, line1B).intersect(QLineF(line2A, line2B), &intersectPoint) == QLineF::BoundedIntersection &&
intersectPoint != line1A && intersectPoint != line1B;
}
...@@ -130,6 +130,8 @@ public: ...@@ -130,6 +130,8 @@ public:
/// Updates the logging filter rules after settings have changed /// Updates the logging filter rules after settings have changed
Q_INVOKABLE void updateLoggingFilterRules(void) { QGCLoggingCategoryRegister::instance()->setFilterRulesFromSettings(QString()); } Q_INVOKABLE void updateLoggingFilterRules(void) { QGCLoggingCategoryRegister::instance()->setFilterRulesFromSettings(QString()); }
Q_INVOKABLE bool linesIntersect(QPointF xLine1, QPointF yLine1, QPointF xLine2, QPointF yLine2);
// Property accesors // Property accesors
FlightMapSettings* flightMapSettings () { return _flightMapSettings; } FlightMapSettings* flightMapSettings () { return _flightMapSettings; }
......
...@@ -179,7 +179,7 @@ void QmlObjectListModel::append(QObject* object) ...@@ -179,7 +179,7 @@ void QmlObjectListModel::append(QObject* object)
insert(_objectList.count(), object); insert(_objectList.count(), object);
} }
QObjectList QmlObjectListModel::swapObjectList(QObjectList newlist) QObjectList QmlObjectListModel::swapObjectList(const QObjectList& newlist)
{ {
QObjectList oldlist(_objectList); QObjectList oldlist(_objectList);
beginResetModel(); beginResetModel();
......
...@@ -37,7 +37,7 @@ public: ...@@ -37,7 +37,7 @@ public:
void setDirty(bool dirty); void setDirty(bool dirty);
void append(QObject* object); void append(QObject* object);
QObjectList swapObjectList(QObjectList newlist); QObjectList swapObjectList(const QObjectList& newlist);
void clear(void); void clear(void);
QObject* removeAt(int i); QObject* removeAt(int i);
QObject* removeOne(QObject* object) { return removeAt(indexOf(object)); } QObject* removeOne(QObject* object) { return removeAt(indexOf(object)); }
......
...@@ -57,28 +57,24 @@ LinuxBuild { ...@@ -57,28 +57,24 @@ LinuxBuild {
$$GST_ROOT/include/gstreamer-1.0 \ $$GST_ROOT/include/gstreamer-1.0 \
$$GST_ROOT/include/glib-2.0 \ $$GST_ROOT/include/glib-2.0 \
$$GST_ROOT/lib/gstreamer-1.0/include \ $$GST_ROOT/lib/gstreamer-1.0/include \
$$GST_ROOT/lib/glib-2.0/include $$GST_ROOT/lib/glib-2.0/include
} COPY_FILE_LIST = \
$$GST_ROOT\\bin\\libffi-6.dll \
COPY_FILE_LIST = \ $$GST_ROOT\\bin\\libglib-2.0-0.dll \
$$GST_ROOT\\bin\\libffi-6.dll \ $$GST_ROOT\\bin\\libgmodule-2.0-0.dll \
$$GST_ROOT\\bin\\libglib-2.0-0.dll \ $$GST_ROOT\\bin\\libgobject-2.0-0.dll \
$$GST_ROOT\\bin\\libgmodule-2.0-0.dll \ $$GST_ROOT\\bin\\libgstbase-1.0-0.dll \
$$GST_ROOT\\bin\\libgobject-2.0-0.dll \ $$GST_ROOT\\bin\\libgstreamer-1.0-0.dll \
$$GST_ROOT\\bin\\libgstbase-1.0-0.dll \ $$GST_ROOT\\bin\\libgstvideo-1.0-0.dll \
$$GST_ROOT\\bin\\libgstreamer-1.0-0.dll \ $$GST_ROOT\\bin\\libintl-8.dll \
$$GST_ROOT\\bin\\libgstvideo-1.0-0.dll \ $$GST_ROOT\\bin\\liborc-0.4-0.dll \
$$GST_ROOT\\bin\\libintl-8.dll \ $$GST_ROOT\\bin\\libwinpthread-1.dll
$$GST_ROOT\\bin\\liborc-0.4-0.dll \ DESTDIR_WIN = $$replace(DESTDIR, "/", "\\")
$$GST_ROOT\\bin\\libwinpthread-1.dll \ for(COPY_FILE, COPY_FILE_LIST) {
QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$COPY_FILE\" \"$$DESTDIR_WIN\"
DESTDIR_WIN = $$replace(DESTDIR, "/", "\\") }
QMAKE_POST_LINK += $$escape_expand(\\n)
for(COPY_FILE, COPY_FILE_LIST) {
QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$COPY_FILE\" \"$$DESTDIR_WIN\"
} }
QMAKE_POST_LINK += $$escape_expand(\\n)
} else:AndroidBuild { } else:AndroidBuild {
#- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2 #- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2
GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2 GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2
......
...@@ -199,6 +199,7 @@ void UASQuickView::resizeEvent(QResizeEvent *evt) ...@@ -199,6 +199,7 @@ void UASQuickView::resizeEvent(QResizeEvent *evt)
} }
void UASQuickView::recalculateItemTextSizing() void UASQuickView::recalculateItemTextSizing()
{ {
return;
int minpixelsize = 65535; int minpixelsize = 65535;
for (QMap<QString,UASQuickViewItem*>::const_iterator i = uasPropertyToLabelMap.constBegin();i!=uasPropertyToLabelMap.constEnd();i++) for (QMap<QString,UASQuickViewItem*>::const_iterator i = uasPropertyToLabelMap.constBegin();i!=uasPropertyToLabelMap.constEnd();i++)
{ {
......
...@@ -14,7 +14,7 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p ...@@ -14,7 +14,7 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p
titleLabel->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Minimum); titleLabel->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Minimum);
titleLabel->setObjectName(QString::fromUtf8("title")); titleLabel->setObjectName(QString::fromUtf8("title"));
QFont titlefont = titleLabel->font(); QFont titlefont = titleLabel->font();
titlefont.setPixelSize(this->height() / 4.0); //titlefont.setPixelSize(this->height() / 4.0);
titleLabel->setFont(titlefont); titleLabel->setFont(titlefont);
layout->addWidget(titleLabel); layout->addWidget(titleLabel);
...@@ -25,7 +25,7 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p ...@@ -25,7 +25,7 @@ UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(p
valueLabel->setObjectName(QString::fromUtf8("value")); valueLabel->setObjectName(QString::fromUtf8("value"));
valueLabel->setText("0.00"); valueLabel->setText("0.00");
QFont valuefont = valueLabel->font(); QFont valuefont = valueLabel->font();
valuefont.setPixelSize(this->height() / 2.0); //valuefont.setPixelSize(this->height() / 2.0);
valueLabel->setFont(valuefont); valueLabel->setFont(valuefont);
layout->addWidget(valueLabel); layout->addWidget(valueLabel);
......
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