SurveyItemEditor.qml 17.4 KB
Newer Older
1 2
import QtQuick          2.3
import QtQuick.Controls 1.2
Don Gagne's avatar
Don Gagne committed
3
import QtQuick.Dialogs  1.2
4
import QtQuick.Extras   1.4
5
import QtQuick.Layouts  1.2
6

7
import QGroundControl               1.0
8 9 10
import QGroundControl.ScreenTools   1.0
import QGroundControl.Vehicle       1.0
import QGroundControl.Controls      1.0
11
import QGroundControl.FactSystem    1.0
12 13
import QGroundControl.FactControls  1.0
import QGroundControl.Palette       1.0
14
import QGroundControl.FlightMap     1.0
15 16 17

Rectangle {
    id:         _root
18
    height:     visible ? (editorColumn.height + (_margin * 2)) : 0
19 20 21 22
    width:      availableWidth
    color:      qgcPal.windowShadeDark
    radius:     _radius

Ricardo de Almeida Gonzaga's avatar
Ricardo de Almeida Gonzaga committed
23
    // The following properties must be available up the hierarchy chain
24 25 26
    //property real   availableWidth    ///< Width for control
    //property var    missionItem       ///< Mission Item for editor

27 28 29
    property real   _margin:                    ScreenTools.defaultFontPixelWidth / 2
    property real   _fieldWidth:                ScreenTools.defaultFontPixelWidth * 10.5
    property var    _vehicle:                   QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle
30
    property real   _cameraMinTriggerInterval:  _missionItem.cameraCalc.minTriggerInterval.rawValue
31
    property bool   _polygonDone:               false
DoinLakeFlyer's avatar
DoinLakeFlyer committed
32
    property string _doneAdjusting:             qsTr("Done")
33 34
    property var    _missionItem:               missionItem
    property bool   _presetsAvailable:          _missionItem.presetNames.length !== 0
Don Gagne's avatar
Don Gagne committed
35

36
    function polygonCaptureStarted() {
37
        _missionItem.clearPolygon()
38
    }
Don Gagne's avatar
Don Gagne committed
39

40 41
    function polygonCaptureFinished(coordinates) {
        for (var i=0; i<coordinates.length; i++) {
42
            _missionItem.addPolygonCoordinate(coordinates[i])
Don Gagne's avatar
Don Gagne committed
43
        }
44
    }
Don Gagne's avatar
Don Gagne committed
45

46
    function polygonAdjustVertex(vertexIndex, vertexCoordinate) {
47
        _missionItem.adjustPolygonCoordinate(vertexIndex, vertexCoordinate)
Don Gagne's avatar
Don Gagne committed
48 49
    }

50 51 52
    function polygonAdjustStarted() { }
    function polygonAdjustFinished() { }

53 54 55 56 57 58 59
    QGCPalette { id: qgcPal; colorGroupEnabled: true }

    Column {
        id:                 editorColumn
        anchors.margins:    _margin
        anchors.top:        parent.top
        anchors.left:       parent.left
60
        anchors.right:      parent.right
61

62
        ColumnLayout {
63
            id:             wizardColumn
64 65
            anchors.left:   parent.left
            anchors.right:  parent.right
66
            spacing:        _margin
67
            visible:        !_missionItem.surveyAreaPolygon.isValid || _missionItem.wizardMode
68

69
            ColumnLayout {
70
                Layout.fillWidth:   true
71 72 73 74 75 76 77 78 79
                spacing:             _margin
                visible:            !_polygonDone

                QGCLabel {
                    Layout.fillWidth:       true
                    wrapMode:               Text.WordWrap
                    horizontalAlignment:    Text.AlignHCenter
                    text:                   qsTr("Use the Polygon Tools to create the polygon which outlines your survey area.")
                }
80
            }
Don Gagne's avatar
Don Gagne committed
81 82
        }

83
        Column {
84 85 86
            anchors.left:   parent.left
            anchors.right:  parent.right
            spacing:        _margin
87
            visible:        !wizardColumn.visible
Don Gagne's avatar
Don Gagne committed
88

89
            TransectStyleComplexItemTabBar {
90
                id:             tabBar
91 92
                anchors.left:   parent.left
                anchors.right:  parent.right
Don Gagne's avatar
Don Gagne committed
93 94
            }

95
            // Grid tab
96 97 98 99
            Column {
                anchors.left:       parent.left
                anchors.right:      parent.right
                spacing:            _margin
100
                visible:            tabBar.currentIndex === 0
101 102 103 104 105 106 107

                QGCLabel {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    text:           qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1))
                    wrapMode:       Text.WordWrap
                    color:          qgcPal.warningText
108
                    visible:        _missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > _missionItem.timeBetweenShots
Don Gagne's avatar
Don Gagne committed
109 110
                }

111
                CameraCalcGrid {
112
                    cameraCalc:                     _missionItem.cameraCalc
113 114
                    vehicleFlightIsFrontal:         true
                    distanceToSurfaceLabel:         qsTr("Altitude")
115
                    distanceToSurfaceAltitudeMode:  _missionItem.followTerrain ?
116
                                                        QGroundControl.AltitudeModeAboveTerrain :
117
                                                        (_missionItem.cameraCalc.distanceToSurfaceRelative ? QGroundControl.AltitudeModeRelative : QGroundControl.AltitudeModeAbsolute)
118 119
                    frontalDistanceLabel:           qsTr("Trigger Dist")
                    sideDistanceLabel:              qsTr("Spacing")
Don Gagne's avatar
Don Gagne committed
120 121
                }

122
                SectionHeader {
123 124 125 126
                    id:             transectsHeader
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    text:           qsTr("Transects")
127
                }
128 129 130 131 132 133 134 135 136 137 138

                GridLayout {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    columnSpacing:  _margin
                    rowSpacing:     _margin
                    columns:        2
                    visible:        transectsHeader.checked

                    QGCLabel { text: qsTr("Angle") }
                    FactTextField {
139
                        fact:                   _missionItem.gridAngle
140
                        Layout.fillWidth:       true
141
                        onUpdated:              angleSlider.value = _missionItem.gridAngle.value
142 143 144 145 146 147 148 149 150 151 152
                    }

                    QGCSlider {
                        id:                     angleSlider
                        minimumValue:           0
                        maximumValue:           359
                        stepSize:               1
                        tickmarksEnabled:       false
                        Layout.fillWidth:       true
                        Layout.columnSpan:      2
                        Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
153 154
                        onValueChanged:         _missionItem.gridAngle.value = value
                        Component.onCompleted:  value = _missionItem.gridAngle.value
155 156 157 158 159 160 161
                        updateValueWhileDragging: true
                    }

                    QGCLabel {
                        text:       qsTr("Turnaround dist")
                    }
                    FactTextField {
162
                        fact:               _missionItem.turnAroundDistance
163 164
                        Layout.fillWidth:   true
                    }
165
                }
DonLakeFlyer's avatar
DonLakeFlyer committed
166

167 168
                QGCButton {
                    text:               qsTr("Rotate Entry Point")
169
                    onClicked:          _missionItem.rotateEntryPoint();
170
                }
Don Gagne's avatar
Don Gagne committed
171

172 173 174 175 176
                ColumnLayout {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    spacing:        _margin
                    visible:        transectsHeader.checked
DonLakeFlyer's avatar
DonLakeFlyer committed
177

178 179 180 181 182 183
                    QGCOptionsComboBox {
                        Layout.fillWidth: true

                        model: [
                            {
                                text:       qsTr("Hover and capture image"),
184 185 186
                                fact:       _missionItem.hoverAndCapture,
                                enabled:    !_missionItem.followTerrain,
                                visible:    _missionItem.hoverAndCaptureAllowed
187 188 189
                            },
                            {
                                text:       qsTr("Refly at 90 deg offset"),
190 191
                                fact:       _missionItem.refly90Degrees,
                                enabled:    !_missionItem.followTerrain,
192 193 194 195
                                visible:    true
                            },
                            {
                                text:       qsTr("Images in turnarounds"),
196 197
                                fact:       _missionItem.cameraTriggerInTurnAround,
                                enabled:    _missionItem.hoverAndCaptureAllowed ? !_missionItem.hoverAndCapture.rawValue : true,
198 199 200 201
                                visible:    true
                            },
                            {
                                text:       qsTr("Fly alternate transects"),
202
                                fact:       _missionItem.flyAlternateTransects,
203 204 205 206 207
                                enabled:    true,
                                visible:    _vehicle ? (_vehicle.fixedWing || _vehicle.vtol) : false
                            },
                            {
                                text:       qsTr("Relative altitude"),
208 209 210
                                enabled:    _missionItem.cameraCalc.isManualCamera && !_missionItem.followTerrain,
                                visible:    QGroundControl.corePlugin.options.showMissionAbsoluteAltitude || (!_missionItem.cameraCalc.distanceToSurfaceRelative && !_missionItem.followTerrain),
                                checked:    _missionItem.cameraCalc.distanceToSurfaceRelative
211 212 213 214 215
                            }
                        ]

                        onItemClicked: {
                            if (index == 4) {
216 217
                                _missionItem.cameraCalc.distanceToSurfaceRelative = !_missionItem.cameraCalc.distanceToSurfaceRelative
                                console.log(_missionItem.cameraCalc.distanceToSurfaceRelative)
218
                            }
219
                        }
220 221
                    }
                }
222

223
                SectionHeader {
224 225 226 227
                    id:             statsHeader
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    text:           qsTr("Statistics")
228 229 230 231 232 233 234 235 236
                }

                TransectStyleComplexItemStats {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    visible:        statsHeader.checked
                }
            } // Grid Column

237
            // Camera Tab
238 239 240 241
            Column {
                anchors.left:       parent.left
                anchors.right:      parent.right
                spacing:            _margin
242
                visible:            tabBar.currentIndex === 1
243 244

                CameraCalcCamera {
245
                    cameraCalc: _missionItem.cameraCalc
246 247
                }
            } // Camera Column
248

249 250 251 252 253 254
            // Terrain Tab
            TransectStyleComplexItemTerrainFollow {
                anchors.left:   parent.left
                anchors.right:  parent.right
                spacing:        _margin
                visible:        tabBar.currentIndex === 2
255
                missionItem:    _missionItem
256 257 258
            }

            // Presets Tab
259
            ColumnLayout {
260 261 262
                anchors.left:       parent.left
                anchors.right:      parent.right
                spacing:            _margin
263
                visible:            tabBar.currentIndex === 3
264

265 266 267 268 269
                QGCLabel {
                    Layout.fillWidth:   true
                    text:               qsTr("Presets")
                    wrapMode:           Text.WordWrap
                }
270

271 272 273
                QGCComboBox {
                    id:                 presetCombo
                    Layout.fillWidth:   true
274
                    model:              _missionItem.presetNames
275
                }
276

277
                RowLayout {
278
                    Layout.fillWidth:   true
279

280
                    QGCButton {
281
                        Layout.fillWidth:   true
282
                        text:               qsTr("Apply Preset")
283 284
                        enabled:            _missionItem.presetNames.length != 0
                        onClicked:          _missionItem.loadPreset(presetCombo.textAt(presetCombo.currentIndex))
285 286
                    }

287
                    QGCButton {
288
                        Layout.fillWidth:   true
289
                        text:               qsTr("Delete Preset")
290
                        enabled:            _missionItem.presetNames.length != 0
291 292 293 294 295 296 297 298
                        onClicked:          mainWindow.showComponentDialog(deletePresetMessage, qsTr("Delete Preset"), mainWindow.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No)

                        Component {
                            id: deletePresetMessage
                            QGCViewMessage {
                                message: qsTr("Are you sure you want to delete '%1' preset?").arg(presetName)
                                property string presetName: presetCombo.textAt(presetCombo.currentIndex)
                                function accept() {
299
                                    _missionItem.deletePreset(presetName)
300 301 302 303
                                    hideDialog()
                                }
                            }
                        }
304
                    }
305
                }
306

307
                Item { height: ScreenTools.defaultFontPixelHeight; width: 1 }
308

Don Gagne's avatar
Don Gagne committed
309
                QGCButton {
310
                    Layout.alignment:   Qt.AlignCenter
Don Gagne's avatar
Don Gagne committed
311
                    Layout.fillWidth:   true
312 313
                    text:               qsTr("Save Settings As New Preset")
                    onClicked:          mainWindow.showComponentDialog(savePresetDialog, qsTr("Save Preset"), mainWindow.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
Don Gagne's avatar
Don Gagne committed
314 315
                }

316 317
                SectionHeader {
                    id:                 presectsTransectsHeader
Don Gagne's avatar
Don Gagne committed
318
                    Layout.fillWidth:   true
319
                    text:               qsTr("Transects")
Don Gagne's avatar
Don Gagne committed
320 321
                }

322 323 324 325 326 327
                GridLayout {
                    Layout.fillWidth:   true
                    columnSpacing:      _margin
                    rowSpacing:         _margin
                    columns:            2
                    visible:            presectsTransectsHeader.checked
328

329 330
                    QGCLabel { text: qsTr("Angle") }
                    FactTextField {
331
                        fact:                   _missionItem.gridAngle
332
                        Layout.fillWidth:       true
333
                        onUpdated:              presetsAngleSlider.value = _missionItem.gridAngle.value
334
                    }
335

336 337 338 339 340 341 342 343 344
                    QGCSlider {
                        id:                     presetsAngleSlider
                        minimumValue:           0
                        maximumValue:           359
                        stepSize:               1
                        tickmarksEnabled:       false
                        Layout.fillWidth:       true
                        Layout.columnSpan:      2
                        Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
345 346
                        onValueChanged:         _missionItem.gridAngle.value = value
                        Component.onCompleted:  value = _missionItem.gridAngle.value
347 348
                        updateValueWhileDragging: true
                    }
349

350 351 352 353
                    QGCButton {
                        Layout.columnSpan:  2
                        Layout.fillWidth:   true
                        text:               qsTr("Rotate Entry Point")
354
                        onClicked:          _missionItem.rotateEntryPoint();
355
                    }
356 357
                }

358
                SectionHeader {
359
                    id:                 presetsStatsHeader
360
                    Layout.fillWidth:   true
361
                    text:               qsTr("Statistics")
362 363
                }

364
                TransectStyleComplexItemStats {
365
                    Layout.fillWidth:   true
366
                    visible:            presetsStatsHeader.checked
367
                }
368 369
            } // Main editing column
        } // Top level  Column
370 371 372 373 374 375 376

        Component {
            id: savePresetDialog

            QGCViewDialog {
                function accept() {
                    if (presetNameField.text != "") {
377
                        _missionItem.savePreset(presetNameField.text)
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
                        hideDialog()
                    }
                }

                ColumnLayout {
                    anchors.left:   parent.left
                    anchors.right:  parent.right
                    spacing:        ScreenTools.defaultFontPixelHeight

                    QGCLabel {
                        Layout.fillWidth:   true
                        text:               qsTr("Save the current settings as a named preset.")
                        wrapMode:           Text.WordWrap
                    }

                    QGCLabel {
                        text: qsTr("Preset Name")
                    }

                    QGCTextField {
                        id:                 presetNameField
                        Layout.fillWidth:   true
                    }
Don Gagne's avatar
Don Gagne committed
401 402 403 404
                }
            }
        }
    }
405 406 407 408 409 410 411

    KMLOrSHPFileDialog {
        id:             kmlOrSHPLoadDialog
        title:          qsTr("Select Polygon File")
        selectExisting: true

        onAcceptedForLoad: {
412 413 414
            _missionItem.surveyAreaPolygon.loadKMLOrSHPFile(file)
            _missionItem.resetState = false
            //editorMap.mapFitFunctions.fitMapViewportTo_missionItems()
415 416 417
            close()
        }
    }
418
} // Rectangle